1
0
Fork 0
mirror of https://github.com/seiichiro0185/sailotp.git synced 2024-11-22 07:39:42 +00:00

Added basic import and export

The DB can be exported to json file
Added handling of duplicate entries
This commit is contained in:
seiichiro 2014-02-01 15:38:09 +01:00
parent 09edf6c8b8
commit 743b06f065
3 changed files with 133 additions and 58 deletions

View file

@ -39,8 +39,7 @@ function getDB() {
db.changeVersion("", "2", db.changeVersion("", "2",
function(tx) { 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);"); tx.executeSql("CREATE TABLE IF NOT EXISTS OTPStorage(title TEXT, secret TEXT, type TEXT DEFAULT 'TOPT', counter INTEGER DEFAULT 0, fav INTEGER DEFAULT 0);");
} });
);
} else if (db.version == "1.0") { } else if (db.version == "1.0") {
// Upgrade DB Schema to Version 2 // Upgrade DB Schema to Version 2
db.changeVersion("1.0", "2", db.changeVersion("1.0", "2",
@ -48,8 +47,7 @@ function getDB() {
tx.executeSql("ALTER TABLE OTPStorage ADD COLUMN type TEXT DEFAULT 'TOTP';"); tx.executeSql("ALTER TABLE OTPStorage ADD COLUMN type TEXT DEFAULT 'TOTP';");
tx.executeSql("ALTER TABLE OTPStorage ADD COLUMN counter INTEGER DEFAULT 0;"); tx.executeSql("ALTER TABLE OTPStorage ADD COLUMN counter INTEGER DEFAULT 0;");
tx.executeSql("ALTER TABLE OTPStorage ADD COLUMN fav INTEGER DEFAULT 0;"); tx.executeSql("ALTER TABLE OTPStorage ADD COLUMN fav INTEGER DEFAULT 0;");
} });
);
} }
} catch (e) { } catch (e) {
// DB Failed to open // DB Failed to open
@ -70,8 +68,57 @@ function getOTP() {
mainPage.appendOTP(res.rows.item(i).title, res.rows.item(i).secret, res.rows.item(i).type, res.rows.item(i).counter, res.rows.item(i).fav); mainPage.appendOTP(res.rows.item(i).title, res.rows.item(i).secret, res.rows.item(i).type, res.rows.item(i).counter, res.rows.item(i).fav);
if (res.rows.item(i).fav) mainPage.setCoverOTP(res.rows.item(i).title, res.rows.item(i).secret, res.rows.item(i).type); if (res.rows.item(i).fav) mainPage.setCoverOTP(res.rows.item(i).title, res.rows.item(i).secret, res.rows.item(i).type);
} }
});
}
// Get all OTP Values and put them into a JSON-Object
function db2json(password) {
var db = getDB();
var otpList = [];
db.transaction(
function(tx) {
var res = tx.executeSql("select * from OTPStorage;");
for (var i=0; i < res.rows.length; i++) {
otpList.push({
"title": res.rows.item(i).title,
"secret": res.rows.item(i).secret,
"type": res.rows.item(i).type,
"counter": res.rows.item(i).counter,
});
}
});
if (otpList.length > 0) {
return(JSON.stringify({"app": "sailotp", "version": 1, "otplist": otpList}));
} else {
return("")
}
}
// Read Values from JSON and put them into the DB
function json2db(jsonString, password) {
var json = JSON.parse(jsonString);
if (json.version != "1" && json.app != "sailotp" ) {
console.log("Unrecognized JSON format");
return(false);
} else {
var otpList = [];
otpList = json.otplist;
if (otpList.length > 0) {
while(otpList.length > 0) {
var otpItem = otpList.shift();
if (otpItem.title != "" & otpItem.secret.length >= 16) {
addOTP(otpItem.title, otpItem.secret, otpItem.type, otpItem.counter);
}
}
parentPage.refreshOTPList();
} else {
console.log("File contains no Items");
return(false);
}
} }
)
} }
// Add a new OTP // Add a new OTP
@ -80,9 +127,26 @@ function addOTP(title, secret, type, counter) {
db.transaction( db.transaction(
function(tx) { function(tx) {
if (checkOTP(title, secret)) {
console.log("Token " + title + " is already in DB");
} else {
tx.executeSql("INSERT INTO OTPStorage VALUES(?, ?, ?, ?, ?);", [title, secret, type, counter, 0]); tx.executeSql("INSERT INTO OTPStorage VALUES(?, ?, ?, ?, ?);", [title, secret, type, counter, 0]);
console.log("Token " + title + " added.");
} }
) });
}
// Check if an OTP Token already exists in the DB
function checkOTP(title, secret) {
var db = getDB();
var res
db.transaction(
function(tx) {
res = tx.executeSql("select title FROM OTPStorage WHERE title=? and secret=?;", [title, secret]);
});
return res.rows.length > 0 ? true : false
} }
// Remove an existing OTP // Remove an existing OTP
@ -92,10 +156,10 @@ function removeOTP(title, secret) {
db.transaction( db.transaction(
function(tx) { function(tx) {
tx.executeSql("DELETE FROM OTPStorage WHERE title=? and secret=?;", [title, secret]); tx.executeSql("DELETE FROM OTPStorage WHERE title=? and secret=?;", [title, secret]);
} });
)
} }
// Set OTP to favourite
function setFav(title, secret) { function setFav(title, secret) {
var db = getDB(); var db = getDB();
@ -103,18 +167,17 @@ function setFav(title, secret) {
function(tx) { function(tx) {
tx.executeSql("UPDATE OTPStorage set fav = 0"); tx.executeSql("UPDATE OTPStorage set fav = 0");
tx.executeSql("UPDATE OTPStorage set fav = 1 WHERE title=? and secret=?;", [title, secret]); tx.executeSql("UPDATE OTPStorage set fav = 1 WHERE title=? and secret=?;", [title, secret]);
} });
)
} }
// Reset favourite Flag for OTP
function resetFav(title, secret) { function resetFav(title, secret) {
var db = getDB(); var db = getDB();
db.transaction( db.transaction(
function(tx) { function(tx) {
tx.executeSql("UPDATE OTPStorage set fav = 0"); tx.executeSql("UPDATE OTPStorage set fav = 0");
} });
)
} }
// Change an existing OTP // Change an existing OTP
@ -123,12 +186,15 @@ function changeOTP(title, secret, type, counter, oldtitle, oldsecret) {
db.transaction( db.transaction(
function(tx) { function(tx) {
if (checkOTP(title, secret)) {
console.log("Token " + title + " is already in DB");
} else {
tx.executeSql("UPDATE OTPStorage SET title=?, secret=?, type=?, counter=? WHERE title=? and secret=?;", [title, secret, type, counter, oldtitle, oldsecret]); tx.executeSql("UPDATE OTPStorage SET title=?, secret=?, type=?, counter=? WHERE title=? and secret=?;", [title, secret, type, counter, oldtitle, oldsecret]);
console.log("Token " + title + " modified.");
} }
) });
} }
// Get the counter for a HOTP value, incerment the counter on request // Get the counter for a HOTP value, incerment the counter on request
function getCounter(title, secret, increment) { function getCounter(title, secret, increment) {
var db = getDB(); var db = getDB();
@ -139,8 +205,7 @@ function getCounter(title, secret, increment) {
function(tx) { function(tx) {
res = tx.executeSql("SELECT counter FROM OTPStorage where title=? and secret=?;", [title, secret]); res = tx.executeSql("SELECT counter FROM OTPStorage where title=? and secret=?;", [title, secret]);
if (increment) tx.executeSql("UPDATE OTPStorage set counter=counter+1 WHERE title=? and secret=?;", [title, secret]); if (increment) tx.executeSql("UPDATE OTPStorage set counter=counter+1 WHERE title=? and secret=?;", [title, secret]);
} });
)
return res.rows.item(0).counter; return res.rows.item(0).counter;
} }

View file

@ -37,6 +37,9 @@ import "../lib/storage.js" as DB // Import the storage library for Config-Access
Dialog { Dialog {
id: exportPage id: exportPage
// We get the Object of the parent page on call to refresh it after adding a new Entry
property QtObject parentPage: null
property string mode: "export" property string mode: "export"
// FileIO Object for reading / writing files // FileIO Object for reading / writing files
@ -90,9 +93,16 @@ Dialog {
canAccept: fileName.text.length > 0 && filePassword.text.length > 0 ? true : false canAccept: fileName.text.length > 0 && filePassword.text.length > 0 ? true : false
// Do the DB-Export / Import // Do the DB-Export / Import
// TODO: Error handling and enctyption
onDone: { onDone: {
if (result == DialogResult.Accepted) { if (result == DialogResult.Accepted) {
// TODO if (mode == "export") {
console.log("Exporting to " + fileName.text, filePassword.text);
exportFile.write(DB.db2json());
} else if(mode == "import") {
console.log("Importing ftom " + fileName.text, filePassword.text);
DB.json2db(exportFile.read(), filePassword)
}
} }
} }
} }

View file

@ -113,7 +113,7 @@ Page {
} }
MenuItem { MenuItem {
text: "Export / Import DB" text: "Export / Import DB"
onClicked: pageStack.push(Qt.resolvedUrl("ExportPage.qml")) onClicked: pageStack.push(Qt.resolvedUrl("ExportPage.qml"), {parentPage: mainPage})
} }
MenuItem { MenuItem {
text: "Add OTP" text: "Add OTP"