From e3fd514d5539f92b2b503af7dc2139bf053960b8 Mon Sep 17 00:00:00 2001 From: Andrey Skvortsov Date: Mon, 14 Nov 2022 19:33:02 +0300 Subject: [PATCH 1/3] Set default DB version to 4.0 --- qml/lib/storage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qml/lib/storage.js b/qml/lib/storage.js index 8414604..fac6cda 100644 --- a/qml/lib/storage.js +++ b/qml/lib/storage.js @@ -36,7 +36,7 @@ function getDB() { if (db.version == "") { // Initialize an empty DB, Create the Table - db.changeVersion("", "3", + db.changeVersion("", "4", function(tx) { tx.executeSql("CREATE TABLE IF NOT EXISTS OTPStorage(title TEXT, secret TEXT, type TEXT DEFAULT 'TOPT', counter INTEGER DEFAULT 0, fav INTEGER DEFAULT 0, sort INTEGER DEFAULT 0, len INTEGER default 6, diff INTEGER default 0);"); }); From 5339deb2df308c53863d3435f079a2ae014b1058 Mon Sep 17 00:00:00 2001 From: Andrey Skvortsov Date: Mon, 14 Nov 2022 21:23:12 +0300 Subject: [PATCH 2/3] Add custom period for TOTP tokens --- qml/cover/CoverPage.qml | 2 +- qml/harbour-sailotp.qml | 6 ++++-- qml/lib/crypto.js | 6 +++--- qml/lib/storage.js | 46 ++++++++++++++++++++++++++--------------- qml/pages/AddOTP.qml | 21 ++++++++++++++++--- qml/pages/MainView.qml | 8 +++---- 6 files changed, 59 insertions(+), 30 deletions(-) diff --git a/qml/cover/CoverPage.qml b/qml/cover/CoverPage.qml index ba7d9a0..09a6bff 100644 --- a/qml/cover/CoverPage.qml +++ b/qml/cover/CoverPage.qml @@ -45,7 +45,7 @@ CoverBackground { var seconds = (curDate.getSeconds() + appWin.coverDiff) % 30 if (lOTP.text == "------" || seconds == 0 || (curDate.getTime() - lastUpdated > 2000)) { - appWin.coverOTP = OTP.calcOTP(appWin.coverSecret, appWin.coverType, appWin.coverLen, appWin.coverDiff, 0); + appWin.coverOTP = OTP.calcOTP(appWin.coverSecret, appWin.coverType, appWin.coverLen, appWin.coverDiff, 0, appWin.coverPeriod); } // Change color of the OTP to red if less than 5 seconds left diff --git a/qml/harbour-sailotp.qml b/qml/harbour-sailotp.qml index 4e7f960..90585a2 100644 --- a/qml/harbour-sailotp.qml +++ b/qml/harbour-sailotp.qml @@ -45,6 +45,7 @@ ApplicationWindow property string coverOTP: "------" property int coverLen: 6 property int coverDiff: 0 + property int coverPeriod: 30 property int coverIndex: 0 // Global Listmodel for Tokens @@ -64,8 +65,8 @@ ApplicationWindow } // Add an entry to the list - function appendOTP(title, secret, type, counter, fav, len, diff) { - listModel.append({"secret": secret, "title": title, "fav": fav, "type": type, "counter": counter, "len": len, "diff": diff, "otp": "------", "itemVisible": true}); + function appendOTP(title, secret, type, counter, fav, len, diff, period) { + listModel.append({"secret": secret, "title": title, "fav": fav, "type": type, "counter": counter, "len": len, "diff": diff, "period": period, "otp": "------", "itemVisible": true}); } // Set the OTP shown on the Cover @@ -76,6 +77,7 @@ ApplicationWindow coverType = listModel.get(index).type; coverLen = listModel.get(index).len; coverDiff = listModel.get(index).diff; + coverPeriod = listModel.get(index).period; coverIndex = index; if (coverType == "TOTP") { coverOTP = "------"; } else { coverOTP = listModel.get(index).otp; } for (var i=0; i 0) { - return(JSON.stringify({"app": "sailotp", "version": 3, "otplist": otpList})); + return(JSON.stringify({"app": "sailotp", "version": 4, "otplist": otpList})); } else { return("") } @@ -122,7 +132,7 @@ function json2db(jsonString, error) { var json = JSON.parse(jsonString); error = ""; - if ((json.version != "1" || json.version != "2" || json.version != "3") && json.app != "sailotp" ) { + if ((json.version != "1" || json.version != "2" || json.version != "3" || json.version != "4") && json.app != "sailotp" ) { error = "Unrecognized format, file is not a SailOTP export"; return(false); } else { @@ -133,13 +143,15 @@ function json2db(jsonString, error) { var otpItem = otpList.shift(); if (otpItem.title != "" & otpItem.secret.length >= 16) { if (json.version == "1") { - addOTP(otpItem.title, otpItem.secret, otpItem.type, otpItem.counter, 0, 6, 0); + addOTP(otpItem.title, otpItem.secret, otpItem.type, otpItem.counter, 0, 6, 0, 30); } else if (json.version == "2") { - addOTP(otpItem.title, otpItem.secret, otpItem.type, otpItem.counter, otpItem.sort, 6, 0); - } else { - addOTP(otpItem.title, otpItem.secret, otpItem.type, otpItem.counter, otpItem.sort, otpItem.len, otpItem.diff); + addOTP(otpItem.title, otpItem.secret, otpItem.type, otpItem.counter, otpItem.sort, 6, 0, 30); + } else if (json.version == "3") { + addOTP(otpItem.title, otpItem.secret, otpItem.type, otpItem.counter, otpItem.sort, otpItem.len, otpItem.diff, 30); + } else { + addOTP(otpItem.title, otpItem.secret, otpItem.type, otpItem.counter, otpItem.sort, otpItem.len, otpItem.diff, otpItem.period); } - } + } } parentPage.refreshOTPList(); return(true); @@ -151,7 +163,7 @@ function json2db(jsonString, error) { } // Add a new OTP -function addOTP(title, secret, type, counter, sort, len, diff) { +function addOTP(title, secret, type, counter, sort, len, diff, period) { var db = getDB(); db.transaction( @@ -159,7 +171,7 @@ function addOTP(title, secret, type, counter, sort, len, diff) { if (checkOTP(title, secret)) { console.log("Token " + title + " is already in DB"); } else { - tx.executeSql("INSERT INTO OTPStorage VALUES(?, ?, ?, ?, ?, ?, ?, ?);", [title, secret, type, counter, 0, sort, len, diff]); + tx.executeSql("INSERT INTO OTPStorage VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?);", [title, secret, type, counter, 0, sort, len, diff, period]); console.log("Token " + title + " added."); } }); @@ -210,12 +222,12 @@ function resetFav(title, secret) { } // Change an existing OTP -function changeOTP(title, secret, type, counter, len, diff, oldtitle, oldsecret) { +function changeOTP(title, secret, type, counter, len, diff, period, oldtitle, oldsecret) { var db = getDB(); db.transaction( function(tx) { - tx.executeSql("UPDATE OTPStorage SET title=?, secret=?, type=?, counter=?, len=?, diff=? WHERE title=? and secret=?;", [title, secret, type, counter, len, diff, oldtitle, oldsecret]); + tx.executeSql("UPDATE OTPStorage SET title=?, secret=?, type=?, counter=?, len=?, diff=?, period=? WHERE title=? and secret=?;", [title, secret, type, counter, len, diff, period, oldtitle, oldsecret]); console.log("Token " + title + " modified."); } ); diff --git a/qml/pages/AddOTP.qml b/qml/pages/AddOTP.qml index f844708..f064ade 100644 --- a/qml/pages/AddOTP.qml +++ b/qml/pages/AddOTP.qml @@ -48,6 +48,7 @@ Dialog { property int paramLen: 6 property int paramDiff: 0 property int paramCounter: 1 // New Counters start at 1 + property int paramPeriod: 30 property bool paramNew: false function checkQR() { @@ -163,6 +164,20 @@ Dialog { EnterKey.iconSource: "image://theme/icon-m-enter-accept" EnterKey.onClicked: addOTP.accept() } + TextField { + id: otpPeriod + width: parent.width + visible: paramType == "TOTP" ? true : false + label: qsTr("Period (Seconds)") + text: paramPeriod + placeholderText: qsTr("Period (Seconds)") + focus: true + horizontalAlignment: TextInput.AlignLeft + validator: IntValidator {} + + EnterKey.iconSource: "image://theme/icon-m-enter-accept" + EnterKey.onClicked: addOTP.accept() + } TextField { id: otpCounter width: parent.width @@ -182,7 +197,7 @@ Dialog { } // Check if we can Save - canAccept: otpLabel.text.length > 0 && otpSecret.text.length >= 16 && otpSecret.acceptableInput && otpLen.text >= 1 && ((paramType == "TOTP" && otpDiff.text != "") || paramType == "TOTP_STEAM" || otpCounter.text.length > 0) ? true : false + canAccept: otpLabel.text.length > 0 && otpSecret.text.length >= 16 && otpSecret.acceptableInput && otpLen.text >= 1 && ((paramType == "TOTP" && otpDiff.text != "" && otpPeriod.text > 0) || paramType == "TOTP_STEAM" || otpCounter.text.length > 0) ? true : false // Save if page is Left with Add onDone: { @@ -190,10 +205,10 @@ Dialog { // Save the entry to the Config DB if (paramLabel != "" && paramKey != "" && !paramNew) { // Parameters where filled -> Change existing entry - DB.changeOTP(otpLabel.text, otpSecret.text, paramType, otpCounter.text, otpLen.text, otpDiff.text, paramLabel, paramKey) + DB.changeOTP(otpLabel.text, otpSecret.text, paramType, otpCounter.text, otpLen.text, otpDiff.text, otpPeriod.text, paramLabel, paramKey) } else { // There were no parameters -> Add new entry - DB.addOTP(otpLabel.text, otpSecret.text, paramType, otpCounter.text, appWin.listModel.count, otpLen.text, otpDiff.text); + DB.addOTP(otpLabel.text, otpSecret.text, paramType, otpCounter.text, appWin.listModel.count, otpLen.text, otpDiff.text, otpPeriod.text); } // Refresh the main Page diff --git a/qml/pages/MainView.qml b/qml/pages/MainView.qml index 9bac121..0f3f9b9 100644 --- a/qml/pages/MainView.qml +++ b/qml/pages/MainView.qml @@ -64,10 +64,10 @@ Page { for (var i=0; i 2000)) { - var curOTP = OTP.calcOTP(appWin.listModel.get(i).secret, appWin.listModel.get(i).type, appWin.listModel.get(i).len, appWin.listModel.get(i).diff, 0); + var curOTP = OTP.calcOTP(appWin.listModel.get(i).secret, appWin.listModel.get(i).type, appWin.listModel.get(i).len, appWin.listModel.get(i).diff, 0, appWin.listModel.get(i).period); appWin.listModel.setProperty(i, "otp", curOTP); } else if (appWin.coverType === "HOTP" && (curDate.getTime() - lastUpdated > 2000) && appWin.listModel.get(i).fav === 1) { // If we are coming back from the CoverPage update OTP value if current favourite is HOTP @@ -311,7 +311,7 @@ Page { MenuItem { text: qsTr("Edit") onClicked: { - pageStack.push(Qt.resolvedUrl("AddOTP.qml"), {parentPage: mainPage, paramLabel: title, paramKey: secret, paramType: type, paramLen: len, paramDiff: diff, paramCounter: DB.getCounter(title, secret, false)}) + pageStack.push(Qt.resolvedUrl("AddOTP.qml"), {parentPage: mainPage, paramLabel: title, paramKey: secret, paramType: type, paramLen: len, paramDiff: diff, paramCounter: DB.getCounter(title, secret, false), paramPeriod: period}) } } MenuItem { From 6bec89dfa27aed420762e4597183ef8eb7de7363 Mon Sep 17 00:00:00 2001 From: Andrey Skvortsov Date: Mon, 14 Nov 2022 21:40:37 +0300 Subject: [PATCH 3/3] Ignore built files --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 88f42f3..9a93b79 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,12 @@ *.pro.user *.pro.user.* *.autosave +*.o +moc_* +documentation.list +harbour-sailotp +RPMS +Makefile rpm/harbour-sailotp.spec rpm/harbour-sailotp.spec.* translations/*.qm