User Tools

Site Tools


Sidebar

Privacy Policy

News

Version 2.50 is out since Jan 1st 2022


Frequently Asked Questions


Namespaces

Note for contributors

If you wish to create a new page in the DroidScript wiki, please click on the most appropriate namespace above and follow the notes for contributors there.

Because of spam, it has been necessary to add a CAPTCHA to the registration form and the save option for editing pages. You will not need to prove you are human if you are logged in, so please register.

Please feel free to improve any existing page, as well as adding new pages to increase the sum of public knowledge about DroidScript.

Formatting Syntax

sample_code:passwordvault

This is an old revision of the document!


Password Vault

This app stores your passwords, protected by FingerPrint scan (if you have set it up) and a Master Password.
The Master Password is only stored in encrypted form, not in plaintext.
Similarly your site/app passwords are only stored in encrypted form.
The encryption keys are not in the code (the keys are your Master Password plus your DeviceID).
After providing your Master Password, you can add sites/apps and passwords.
Touching an entry in the list of sites and passwords shows a dialog
where you can copy the password to the clipboard (to pass into the app/site)
or edit the entry and save, or delete.

Requires the Biometric plugin (or you could comment out that code)

passwordvault.js
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 () {
//    db = app.OpenDatabase( "Vault" ) // does not work as APK  
    db = app.OpenDatabase(app.GetSpecialFolder("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) {
    add = app.AddButton(lay,"[fa-plus-square-o] Add",null,null,"fontawesome")
    add.SetOnTouch(insert)
    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 = app.AddList(lay,str,0.8)
    lst.SetTextSize2(18,"px")
    lst.SetOnTouch(show)
} // 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()
}
sample_code/passwordvault.1658766129.txt.gz · Last modified: 2022/07/25 16:22 by al4he6