2014-01-05 20:58:25 +00:00
/ *
* Copyright ( c ) 2013 , Stefan Brand < seiichiro @ seiichiro0185 . org >
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without modification ,
* are permitted provided that the following conditions are met :
*
2014-02-01 14:38:09 +00:00
* 1. Redistributions of source code must retain the above copyright notice , this
2014-01-05 20:58:25 +00:00
* list of conditions and the following disclaimer .
*
* 2. Redistributions in binary form must reproduce the above copyright notice , this
2014-02-01 14:38:09 +00:00
* list of conditions and the following disclaimer in the documentation and / or other
2014-01-05 20:58:25 +00:00
* materials provided with the distribution .
2014-02-01 14:38:09 +00:00
*
* 3. The names of the contributors may not be used to endorse or promote products
2014-01-05 20:58:25 +00:00
* derived from this software without specific prior written permission .
*
2014-02-01 14:38:09 +00:00
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO ,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
* ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
* LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING
* NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE ,
2014-01-05 20:58:25 +00:00
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* /
. import QtQuick . LocalStorage 2.0 as LS
2014-01-09 18:56:26 +00:00
// Get DB Connection, Initialize or Upgrade DB
2014-01-05 20:58:25 +00:00
function getDB ( ) {
2014-01-09 18:56:26 +00:00
try {
var db = LS . LocalStorage . openDatabaseSync ( "harbour-sailotp" , "" , "SailOTP Config Storage" , 1000000 ) ;
2014-01-05 20:58:25 +00:00
2014-01-09 18:56:26 +00:00
if ( db . version == "" ) {
// Initialize an empty DB, Create the Table
2022-11-14 16:33:02 +00:00
db . changeVersion ( "" , "4" ,
2014-01-09 18:56:26 +00:00
function ( tx ) {
2016-07-14 11:41:00 +00:00
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);" ) ;
2014-02-01 14:38:09 +00:00
} ) ;
2014-01-09 18:56:26 +00:00
} else if ( db . version == "1.0" ) {
2016-07-14 11:41:00 +00:00
// Upgrade DB Schema to Version 4
db . changeVersion ( "1.0" , "4" ,
2014-01-09 18:56:26 +00:00
function ( tx ) {
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 fav INTEGER DEFAULT 0;" ) ;
2014-05-24 13:42:52 +00:00
tx . executeSql ( "ALTER TABLE OTPStorage ADD COLUMN sort INTEGER DEFAULT 0;" ) ;
2016-07-14 11:41:00 +00:00
tx . executeSql ( "ALTER TABLE OTPStorage ADD COLUMN len INTEGER DEFAULT 6;" ) ;
tx . executeSql ( "ALTER TABLE OTPStorage ADD COLUMN diff INTEGER DEFAULT 0;" ) ;
2014-02-01 14:38:09 +00:00
} ) ;
2014-05-24 13:42:52 +00:00
} else if ( db . version == "2" ) {
// Upgrade DB Schema to Version 3
2016-07-14 11:41:00 +00:00
db . changeVersion ( "2" , "4" ,
2014-05-24 13:42:52 +00:00
function ( tx ) {
tx . executeSql ( "ALTER TABLE OTPStorage ADD COLUMN sort INTEGER DEFAULT 0;" ) ;
2016-07-14 11:41:00 +00:00
tx . executeSql ( "ALTER TABLE OTPStorage ADD COLUMN len INTEGER DEFAULT 6;" ) ;
tx . executeSql ( "ALTER TABLE OTPStorage ADD COLUMN diff INTEGER DEFAULT 0;" ) ;
} ) ;
} else if ( db . version == "3" ) {
// Upgrade DB Schema to Version 4
db . changeVersion ( "3" , "4" ,
function ( tx ) {
tx . executeSql ( "ALTER TABLE OTPStorage ADD COLUMN len INTEGER DEFAULT 6;" ) ;
tx . executeSql ( "ALTER TABLE OTPStorage ADD COLUMN diff INTEGER DEFAULT 0;" ) ;
2014-05-24 13:42:52 +00:00
} ) ;
2014-01-06 19:08:16 +00:00
}
2014-01-09 18:56:26 +00:00
} catch ( e ) {
// DB Failed to open
console . log ( "Could not open DB: " + e ) ;
}
return db ;
2014-01-05 20:58:25 +00:00
}
// Get all OTPs into the list model
function getOTP ( ) {
2014-01-06 19:08:16 +00:00
var db = getDB ( ) ;
2014-01-05 20:58:25 +00:00
2014-01-06 19:08:16 +00:00
db . transaction (
function ( tx ) {
2014-05-24 13:42:52 +00:00
var res = tx . executeSql ( "select * from OTPStorage order by sort;" ) ;
2014-01-06 19:08:16 +00:00
for ( var i = 0 ; i < res . rows . length ; i ++ ) {
2016-07-14 11:41:00 +00:00
appWin . 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 , res . rows . item ( i ) . len , res . rows . item ( i ) . diff ) ;
2014-02-09 09:50:58 +00:00
if ( res . rows . item ( i ) . fav ) appWin . setCover ( i ) ;
2014-01-06 19:08:16 +00:00
}
2014-02-01 14:38:09 +00:00
} ) ;
}
// Get all OTP Values and put them into a JSON-Object
2014-02-01 16:06:34 +00:00
function db2json ( ) {
2014-02-01 14:38:09 +00:00
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 ,
2014-05-24 13:42:52 +00:00
"sort" : res . rows . item ( i ) . sort ,
2016-07-14 11:41:00 +00:00
"len" : res . rows . item ( i ) . len ,
"diff" : res . rows . item ( i ) . diff ,
2014-02-01 14:38:09 +00:00
} ) ;
2014-01-06 19:08:16 +00:00
}
2014-02-01 14:38:09 +00:00
} ) ;
if ( otpList . length > 0 ) {
2016-07-14 11:41:00 +00:00
return ( JSON . stringify ( { "app" : "sailotp" , "version" : 3 , "otplist" : otpList } ) ) ;
2014-02-01 14:38:09 +00:00
} else {
return ( "" )
}
}
// Read Values from JSON and put them into the DB
2014-02-02 13:14:59 +00:00
function json2db ( jsonString , error ) {
2014-02-01 14:38:09 +00:00
var json = JSON . parse ( jsonString ) ;
2014-02-02 13:14:59 +00:00
error = "" ;
2014-02-01 14:38:09 +00:00
2016-07-14 11:41:00 +00:00
if ( ( json . version != "1" || json . version != "2" || json . version != "3" ) && json . app != "sailotp" ) {
2014-02-02 13:14:59 +00:00
error = "Unrecognized format, file is not a SailOTP export" ;
2014-02-01 14:38:09 +00:00
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 ) {
2014-05-24 13:42:52 +00:00
if ( json . version == "1" ) {
2016-07-14 11:41:00 +00:00
addOTP ( otpItem . title , otpItem . secret , otpItem . type , otpItem . counter , 0 , 6 , 0 ) ;
} else if ( json . version == "2" ) {
addOTP ( otpItem . title , otpItem . secret , otpItem . type , otpItem . counter , otpItem . sort , 6 , 0 ) ;
2014-05-24 13:42:52 +00:00
} else {
2016-07-14 11:41:00 +00:00
addOTP ( otpItem . title , otpItem . secret , otpItem . type , otpItem . counter , otpItem . sort , otpItem . len , otpItem . diff ) ;
2014-05-24 13:42:52 +00:00
}
2014-02-01 14:38:09 +00:00
}
}
parentPage . refreshOTPList ( ) ;
2014-02-02 13:14:59 +00:00
return ( true ) ;
2014-02-01 14:38:09 +00:00
} else {
2014-02-02 13:14:59 +00:00
error = "File contains no Tokens" ;
2014-02-01 14:38:09 +00:00
return ( false ) ;
}
}
2014-01-05 20:58:25 +00:00
}
// Add a new OTP
2016-07-14 11:41:00 +00:00
function addOTP ( title , secret , type , counter , sort , len , diff ) {
2014-01-06 19:08:16 +00:00
var db = getDB ( ) ;
2014-01-05 20:58:25 +00:00
2014-01-06 19:08:16 +00:00
db . transaction (
function ( tx ) {
2014-02-01 14:38:09 +00:00
if ( checkOTP ( title , secret ) ) {
console . log ( "Token " + title + " is already in DB" ) ;
} else {
2016-07-14 11:41:00 +00:00
tx . executeSql ( "INSERT INTO OTPStorage VALUES(?, ?, ?, ?, ?, ?, ?, ?);" , [ title , secret , type , counter , 0 , sort , len , diff ] ) ;
2014-02-01 14:38:09 +00:00
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
2014-01-05 20:58:25 +00:00
}
// Remove an existing OTP
function removeOTP ( title , secret ) {
2014-01-06 19:08:16 +00:00
var db = getDB ( ) ;
2014-01-05 20:58:25 +00:00
2014-01-06 19:08:16 +00:00
db . transaction (
function ( tx ) {
tx . executeSql ( "DELETE FROM OTPStorage WHERE title=? and secret=?;" , [ title , secret ] ) ;
2014-02-01 14:38:09 +00:00
} ) ;
2014-01-05 20:58:25 +00:00
}
2014-01-08 18:13:53 +00:00
2014-02-01 14:38:09 +00:00
// Set OTP to favourite
2014-01-09 21:12:55 +00:00
function setFav ( title , secret ) {
var db = getDB ( ) ;
db . transaction (
function ( tx ) {
tx . executeSql ( "UPDATE OTPStorage set fav = 0" ) ;
tx . executeSql ( "UPDATE OTPStorage set fav = 1 WHERE title=? and secret=?;" , [ title , secret ] ) ;
2014-02-01 14:38:09 +00:00
} ) ;
2014-01-09 21:12:55 +00:00
}
2014-02-01 14:38:09 +00:00
// Reset favourite Flag for OTP
2014-01-10 18:20:52 +00:00
function resetFav ( title , secret ) {
var db = getDB ( ) ;
db . transaction (
function ( tx ) {
tx . executeSql ( "UPDATE OTPStorage set fav = 0" ) ;
2014-02-01 14:38:09 +00:00
} ) ;
2014-01-10 18:20:52 +00:00
}
2014-01-08 18:13:53 +00:00
// Change an existing OTP
2016-07-14 11:41:00 +00:00
function changeOTP ( title , secret , type , counter , len , diff , oldtitle , oldsecret ) {
2014-01-08 18:13:53 +00:00
var db = getDB ( ) ;
db . transaction (
function ( tx ) {
2016-07-14 11:41:00 +00:00
tx . executeSql ( "UPDATE OTPStorage SET title=?, secret=?, type=?, counter=?, len=?, diff=? WHERE title=? and secret=?;" , [ title , secret , type , counter , len , diff , oldtitle , oldsecret ] ) ;
2014-02-01 14:38:09 +00:00
console . log ( "Token " + title + " modified." ) ;
}
2015-12-06 17:47:13 +00:00
) ;
2014-01-08 18:13:53 +00:00
}
2014-01-12 17:03:23 +00:00
2014-05-24 13:42:52 +00:00
function changeOTPSort ( title , secret , sort ) {
var db = getDB ( ) ;
db . transaction (
function ( tx ) {
if ( ! checkOTP ( title , secret ) ) {
console . log ( "Token " + title + " is not in DB" ) ;
} else {
tx . executeSql ( "UPDATE OTPStorage SET sort=? WHERE title=? and secret=?;" , [ sort , title , secret ] ) ;
console . log ( "Token " + title + " modified." ) ;
}
} ) ;
}
2014-01-12 17:03:23 +00:00
// Get the counter for a HOTP value, incerment the counter on request
function getCounter ( title , secret , increment ) {
var db = getDB ( ) ;
var res = "" ;
db . transaction (
function ( tx ) {
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 ] ) ;
2014-02-01 14:38:09 +00:00
} ) ;
2014-01-12 17:03:23 +00:00
return res . rows . item ( 0 ) . counter ;
}