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
2014-06-19 23:23:22 +00:00
db . changeVersion ( "" , "3" ,
2014-01-09 18:56:26 +00:00
function ( tx ) {
2014-05-24 13:42:52 +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);" ) ;
2014-02-01 14:38:09 +00:00
} ) ;
2014-01-09 18:56:26 +00:00
} else if ( db . version == "1.0" ) {
2014-05-24 13:42:52 +00:00
// Upgrade DB Schema to Version 3
db . changeVersion ( "1.0" , "3" ,
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;" ) ;
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
db . changeVersion ( "2" , "3" ,
function ( tx ) {
tx . executeSql ( "ALTER TABLE OTPStorage ADD COLUMN sort INTEGER DEFAULT 0;" ) ;
} ) ;
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 ++ ) {
2014-05-24 13:42:52 +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 ) . sort ) ;
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 ,
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 ) {
2014-05-24 13:42:52 +00:00
return ( JSON . stringify ( { "app" : "sailotp" , "version" : 2 , "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
2014-05-24 13:42:52 +00:00
if ( ( json . version != "1" || json . version != "2" ) && 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" ) {
addOTP ( otpItem . title , otpItem . secret , otpItem . type , otpItem . counter , 0 ) ;
} else {
addOTP ( otpItem . title , otpItem . secret , otpItem . type , otpItem . counter , otpItem . sort ) ;
}
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
2014-05-24 13:42:52 +00:00
function addOTP ( title , secret , type , counter , sort ) {
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 {
2014-05-24 13:42:52 +00:00
tx . executeSql ( "INSERT INTO OTPStorage VALUES(?, ?, ?, ?, ?, ?);" , [ title , secret , type , counter , 0 , sort ] ) ;
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
2014-01-12 17:03:23 +00:00
function changeOTP ( title , secret , type , counter , oldtitle , oldsecret ) {
2014-01-08 18:13:53 +00:00
var db = getDB ( ) ;
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 {
tx . executeSql ( "UPDATE OTPStorage SET title=?, secret=?, type=?, counter=? WHERE title=? and secret=?;" , [ title , secret , type , counter , oldtitle , oldsecret ] ) ;
console . log ( "Token " + title + " modified." ) ;
}
} ) ;
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 ;
}