app.LoadPlugin( "Biometric" ) var mpw // plaintext master password var empw // encrypted master password function OnStart() { salt = app.GetDeviceId() crpt = app.CreateCrypt() bio = app.CreateBiometric() lay = app.CreateLayout( "Linear", "Top,Left" ) txt = app.AddText(lay,"Password Vault") txt.SetTextSize(18) app.AddLayout( lay ) if(!bio.IsHardwareDetected()) getMasterPassword() else if(!bio.HasEnrolledFingerprints()) { app.ShowPopup("We would recommend setting up fingerprint security") getMasterPassword() } else { adlg = bio.CreateAuthDialog("Please scan your fingerprint", "Vault") adlg.SetOnSuccess(getMasterPassword) adlg.SetOnClose(function () {app.Quit("Exiting");}) adlg.Show() } // if } // fn function getMasterPassword () { //app.ClearData() // testing empw = app.LoadText("empw","") empw = empw.trim() // seems necessary if (empw == "") {option = "";} else {option = ",password";} te = app.AddTextEdit(lay,"",null,null,"singleline,nospell"+option) te.SetHint("Enter Master Password") te.Focus() if (empw == "") {te.SetOnEnter(newMasterPassword);} else {te.SetOnEnter(checkMasterPassword);} app.ShowKeyboard(te) } // fn function newMasterPassword() { mpw = this.GetText() if (mpw.length < 4) app.ShowPopup("Minimum length for Master Password is 4 characters") else {this.Hide() ; empw = crpt.Encrypt(mpw,mpw+salt) ; app.SaveText("empw",empw); opendb();} } // fn function checkMasterPassword() { gt = this.GetText() egt = crpt.Encrypt(gt,gt+salt) // encrypt user input egt = egt.trim() // seems necessary if (egt != empw) app.ShowPopup("Master Password doesn't match!") else {this.Hide(); mpw = gt ; opendb()} } // fn function opendb () { add = app.AddButton(lay,"[fa-plus-square-o] Add",null,null,"fontawesome") add.SetOnTouch(insert) lst = app.AddList(lay,"",0.8) lst.SetTextSize2(18,"px") lst.SetOnTouch(show) // db = app.OpenDatabase( "Vault" ) // does not work as APK db = app.OpenDatabase(app.GetPrivateFolder("Downloads")+"/Vault" ) db.ExecuteSql("CREATE TABLE IF NOT EXISTS passwords (site text primary key, epw text)") //db.ExecuteSql("DELETE FROM passwords",[],null,delError) // testing //epw = crpt.Encrypt("home",mpw+salt) // testing //db.ExecuteSql("INSERT INTO passwords (site, epw) VALUES (?,?)", ["home", epw], null, insError ) // testing db.ExecuteSql( "select * from passwords order by site;", [], display ) app.EnableBackKey(false) // close database if app closed } // fn function display(results) { var str = ""; for (var i = 0; i < results.rows.length; i++ ) { var item = results.rows.item(i) site = item.site epw = item.epw pw = crpt.Decrypt(epw,mpw+salt) if (str != "") str+="," str += site+":"+pw+":" } // for lst.SetList(str) } // fn function insert() { if (typeof dlgi == "undefined") { dlgi = app.CreateDialog("Add","old") layDlgi = app.CreateLayout("linear","left,vertical") layDlgi.SetSize(0.5,-1) dlgi.AddLayout(layDlgi) sa = app.AddTextEdit(layDlgi,"",null,null,"singleline,nospell") sa.SetHint("site or app") pwi = app.AddTextEdit(layDlgi,"",null,null,"singleline,nospell") pwi.SetHint("password") ent = app.AddButton(layDlgi,"[fa-save] Save",null,null,"fontawesome") ent.SetOnTouch(function () { i1 = sa.GetText() ; i2 = pwi.GetText() ; i2e = crpt.Encrypt(i2,mpw+salt) db.ExecuteSql("INSERT INTO passwords (site, epw) VALUES (?,?)", [i1,i2e], insSuccess, insError ) }) } else { sa.SetText("") pwi.SetText("") } dlgi.Show() app.ShowKeyboard(sa) } function show(title,body,icon,index) { gtitle = title if (typeof dlg == "undefined") { dlg = app.CreateDialog(title,"old") layDlg = app.CreateLayout("linear","left,vertical") layDlg.SetSize(0.5,-1) dlg.AddLayout(layDlg) row2 = app.AddLayout(layDlg,"linear","horizontal") cp2 = app.AddButton(row2,"[fa-copy] Copy",null,null,"fontawesome") cp2.SetOnTouch(function() {app.SetClipboardText(bdy.GetText());cp2.Focus();}) bdy = app.AddTextEdit(row2,body,null,null,"singleline,nospell") sve = app.AddButton(layDlg,"[fa-save] Save",null,null,"fontawesome") sve.SetOnTouch(function() { pw = bdy.GetText() ; epw = crpt.Encrypt(pw,mpw+salt); lst.SetItem(gtitle,gtitle,pw) db.ExecuteSql("UPDATE passwords SET epw = ? where site=? ;",[epw,gtitle],updSuccess,updError) dlg.Hide() }) del = app.AddButton(layDlg,"[fa-minus-square-o] Delete",null,null,"fontawesome") del.SetOnTouch(function() { lst.RemoveItem(gtitle) db.ExecuteSql("DELETE FROM passwords where site=?;",[gtitle],delSuccess,delError) dlg.Hide() }) } else { dlg.SetTitle(title) bdy.SetText(body) } dlg.Show() } function insSuccess(msg) { lst.AddItem(i1,i2) dlgi.Hide() } function insError(msg) { alert(msg) app.ShowPopup("insert failed, site/app must be unique") } function updSuccess(msg) { // alert(msg.rowsAffected) app.ShowPopup("updated") } function updError(msg) { alert(msg) app.ShowPopup("update failed") } function delSuccess(msg) { // alert(msg.rowsAffected) app.ShowPopup("deleted") } function delError(msg) { alert(msg) app.ShowPopup("delete failed") } function OnBack() { db.Close() app.Exit() }