# Modules.EncryptedDatabase

Provides transparent, secure 256-bit AES encryption of SQLite database files.

Availability
1.0.0
1.0.0

# Overview

This module exposes the same API as Titanium.Database, but it encrypts all content (even the schema) using a password you specify.

Note: This feature requires a Pro or Enterprise subscription. More info here!

# Getting Started

# Accessing the Module

  • Use require to access this module from JavaScript:

    var encryptedDatabase = require('appcelerator.encrypteddatabase');
    

    The encryptedDatabase variable is a reference to the Module object.

# Example applications

  • Example applications are located in the example folder of the module:

    • ToDo Alloy demonstrates how to use this module with Alloy.
    • JSON1-Extension demonstrates how to use the SQLite JSON1 extension

# Examples

# Open an encrypted database

var DB = require('appcelerator.encrypteddatabase');
var instance = null;
var dataTofetch = null;
var win = Ti.UI.createWindow({
    backgroundColor: 'white'
});
win.addEventListener('open', function () {
    init();
    setup();
    insert();
    fetch();
    closeDB();
});
var indicator = Ti.UI.createActivityIndicator({
    color: 'green',
    message: 'Upgrading database ...',
    style: Ti.UI.ActivityIndicatorStyle.DARK,
    top: 100,
    height: Ti.UI.SIZE,
    width: Ti.UI.SIZE
});
function init() {
    // iOS: check if cipher upgrade is required
    if (Ti.Platform.osname === 'iphone' || Ti.Platform.osname === 'ipad') {
        if (DB.isCipherUpgradeRequired) {
            // check if cipher upgrade required.
            if (DB.isCipherUpgradeRequired('test.db')) {
                Ti.API.info('upgrade of database required');
                indicator.show();
                DB.password = 'secret';
                Ti.API.info('Opening DB ...');
                instance = DB.open('test.db');
                indicator.hide();
                Ti.API.info('database upgrade complete');
                return;
            }
        }
    }
    DB.password = 'secret';
    Ti.API.info('Opening DB ...');
    instance = DB.open('test.db');
}
function setup() {
    instance.execute('CREATE TABLE IF NOT EXISTS testtable(id integer PRIMARY KEY);');
    instance.execute('INSERT OR IGNORE INTO testtable(id) VALUES (1);');
}
function insert() {
    var dataToInsertHandle = instance.execute('SELECT id FROM testtable ORDER BY id DESC LIMIT 1;');
    var dataToInsert = null;
    if(dataToInsertHandle.isValidRow()) {
        dataToInsert = (dataToInsertHandle.fieldByName('id') + 1);
        dataTofetch = dataToInsert;
    }
    instance.execute('INSERT OR IGNORE INTO testtable(id) VALUES (' + dataToInsert + ');');
}
function fetch() {
    var rowValue = null;
    var rowHandle = instance.execute('SELECT * FROM testtable WHERE id=' + dataTofetch + ';');
    if (rowHandle.isValidRow()) {
        rowValue = rowHandle.fieldByName('id');
    }
    alert('Fetched Data: ' + rowValue);
}
function closeDB() {
    instance.close();
}
win.add(indicator);
win.open();

# Use the JSON1-extension to encode/decode JSON-based content

var DB = require('appcelerator.encrypteddatabase');

var win = Ti.UI.createWindow({ backgroundColor: 'white' });
var btn = Ti.UI.createButton({ title: 'Trigger' });

btn.addEventListener('click', accessDatabase);

win.add(btn);
win.open();

function accessDatabase() {
    DB.password = 'secret';

    Ti.API.info('Opening DB ...');
    var instance = DB.open('test.db');

    instance.execute('CREATE TABLE IF NOT EXISTS user(name string, phone string);');
    instance.execute('INSERT into user (name, phone) VALUES("oz", json(\'{"cell":"+491765", "home":"+498973"}\'));');

    var dataToInsertHandle = instance.execute('select user.phone from user where user.name==\'oz\'');
    var result = dataToInsertHandle.isValidRow() ? dataToInsertHandle.fieldByName('phone') : null;

    alert('Fetched data: ' + result);
    Ti.API.info('Closing DB ...');
    instance.close();
}

# Properties

# apiName READONLY

Availability
3.2.0
3.2.0
apiName :String

The name of the API that this proxy corresponds to.

The value of this property is the fully qualified name of the API. For example, Titanium.UI.Button returns Ti.UI.Button.


# bubbleParent

Availability
3.0.0
3.0.0
bubbleParent :Boolean

Indicates if the proxy will bubble an event to its parent.

Some proxies (most commonly views) have a relationship to other proxies, often established by the add() method. For example, for a button added to a window, a click event on the button would bubble up to the window. Other common parents are table sections to their rows, table views to their sections, and scrollable views to their views. Set this property to false to disable the bubbling to the proxy's parent.

Default: true


# hmacAlgorithm

Availability
3.3.0
2.1.0
hmacAlgorithm :Number

The hashing algorithm the encrypted database will use.

This property must be assigned before calling the open() method for it to be applied to the database.

When opening an existing database that was using a different KDF value than what's currently assigned, then it will be automatically migrated. How long the migration takes depends on the size of the database.

Default: Modules.EncryptedDatabase.HMAC_SHA512


# hmacKdfIterations

Availability
3.3.0
2.1.0
hmacKdfIterations :Number

Number of iterations that the KDF (Key Derivation Function) will use for hashing.

Integer where the higher the value, the more secure the generated key will be at the cost of performance. The minimum value allowed is 4000.

Older versions of this module defaulted to 64000, which made database operations faster (but less secure) compared to the newest module versions. If you want to restore the older version's performance, then use this property to change it back to 64000 iterations.

This property must be assigned before calling the open() method for it to be applied to the database.

When opening an existing database that was using a different KDF value than what's currently assigned, then it will be automatically migrated. How long the migration takes depends on the size of the database.

Default: 256000


# lifecycleContainer

Availability
3.6.0

The Window or TabGroup whose Activity lifecycle should be triggered on the proxy.

If this property is set to a Window or TabGroup, then the corresponding Activity lifecycle event callbacks will also be called on the proxy. Proxies that require the activity lifecycle will need this property set to the appropriate containing Window or TabGroup.


# password

Availability
1.0.0
1.0.0
password :String

The password used to encrypt sensitive data.

# Methods

# addEventListener

Availability
1.0.0
1.0.0
addEventListener(name, callback) void

Adds the specified callback as an event listener for the named event.

Parameters

Name Type Description
name String

Name of the event.

callback Callback<Titanium.Event>

Callback function to invoke when the event is fired.

Returns

Type
void

# applyProperties

Availability
3.0.0
3.0.0
applyProperties(props) void

Applies the properties to the proxy.

Properties are supplied as a dictionary. Each key-value pair in the object is applied to the proxy such that myproxy[key] = value.

Parameters

Name Type Description
props Dictionary

A dictionary of properties to apply.

Returns

Type
void

# cipherUpgrade

Availability
1.3.1
cipherUpgrade(name) CipherUpgradeResult

Upgrades sqlcipher used in database.

This method can be used to upgrade the sqlcipher used in the database, when upgrading from an existing app that uses this module from version 1.0.0 to 1.3.1. Make sure the password is set before using this method. Alternatively, using database.open() would also update the sqlcipher if the module detects that it's using an older version. This method is optional to give developers more flexibility when doing version upgrade on apps.

Parameters

Name Type Description
name String

database name

Returns


# fireEvent

Availability
1.0.0
1.0.0
fireEvent(name[, event]) void

Fires a synthesized event to any registered listeners.

Parameters

Name Type Description
name String

Name of the event.

event Dictionary

A dictionary of keys and values to add to the Titanium.Event object sent to the listeners.

Returns

Type
void

# install

Availability
1.0.0
1.0.0
install(path, dbName) Titanium.Database.DB

Installs an SQLite database to device's internal storage.

Copies an SQLite database file to the device's internal storage (only) and creates a persistent name that is available for the lifetime of the app. On Android, if the source file does not exist, an empty database is created.

Returns a reference to the opened database. If the destination file already exists, behaves as open.

This method is primarily used for iOS.

With Android, as there is often minimal internal storage available, install may only be appropriate for small databases or for prototyping. When database files are to be stored on external storage (for example, SD Card), a combination of Titanium.Filesystem and open is required.

With Titanium 1.8.0.1 on iOS, the default database location changed in accordance with Apple's guidelines. If a database file already exists in the old location, install will automatically move it to the new location rather than copying the file from the path provided in the first argument.

Files stored in the Private Documents directory on iOS5 will be automatically backed up to iCloud and removed from the device in low storage situations. See How do I prevent files from being backed up to iCloud and iTunes? for details. To prevent this for database files, use the file object with the remoteBackup property.

Always close the database after use.

Parameters

Name Type Description
path String

Path and filename of the database file to copy to internal storage. File location is relative to the script's context unless an absolute path, such as one constructed with a Titanium.Filesystem constant, is used.

dbName String

Destination filename or absolute path, which will subsequently be passed to open.

Returns


# isCipherUpgradeRequired

Availability
1.3.1
isCipherUpgradeRequired(name) Boolean

Checks and returns if sqlcipher is required to be updated

This is a check to see if the database is using an older version of sqlcipher. Use this to check before opening the database, so that you could prompt or inform the user that it might take a while for database.open() to execute completely, since calling database.open() does the updating internally, and it might take a while depending on how big the database is. Returns true if required, otherwise false.

Parameters

Name Type Description
name String

database name

Returns

Type
Boolean

# open

Availability
1.0.0
1.0.0
open(dbName) Titanium.Database.DB

Opens an SQLite database.

Opens an SQLite database and returns a reference to it. If the database does not exist, creates an empty database file and returns a reference to this opened database.

With Titanium 1.8.0.1 on iOS, the default database location changed in accordance with Apple's guidelines. If a database file already exists in the old location, open will automatically move it to the new location.

Always close the database after use.

Parameters

Name Type Description
dbName String

The dbname previously passed to install. An absolute path to the file, including one that is constructed with a Titanium.Filesystem constant or directoryForSuite method, may be used.

Returns


# removeEventListener

Availability
1.0.0
1.0.0
removeEventListener(name, callback) void

Removes the specified callback as an event listener for the named event.

Multiple listeners can be registered for the same event, so the callback parameter is used to determine which listener to remove.

When adding a listener, you must save a reference to the callback function in order to remove the listener later:

var listener = function() { Ti.API.info("Event listener called."); }
window.addEventListener('click', listener);

To remove the listener, pass in a reference to the callback function:

window.removeEventListener('click', listener);

Parameters

Name Type Description
name String

Name of the event.

callback Callback<Titanium.Event>

Callback function to remove. Must be the same function passed to addEventListener.

Returns

Type
void

# Constants

# FIELD_TYPE_DOUBLE

Availability
1.0.0
1.0.0
FIELD_TYPE_DOUBLE :Number

Constant for requesting a column's value returned in double form.


# FIELD_TYPE_FLOAT

Availability
1.0.0
1.0.0
FIELD_TYPE_FLOAT :Number

Constant for requesting a column's value returned in float form.


# FIELD_TYPE_INT

Availability
1.0.0
1.0.0
FIELD_TYPE_INT :Number

Constant for requesting a column's value returned in integer form.


# FIELD_TYPE_STRING

Availability
1.0.0
1.0.0
FIELD_TYPE_STRING :Number

Constant for requesting a column's value returned in string form.


# HMAC_SHA1

Availability
3.3.0
2.1.0
HMAC_SHA1 :Number

Assigned to hmacAlgorithm to hash with SHA1.


# HMAC_SHA256

Availability
3.3.0
2.1.0
HMAC_SHA256 :Number

Assigned to hmacAlgorithm to hash with SHA256.


# HMAC_SHA512

Availability
3.3.0
2.1.0
HMAC_SHA512 :Number

Assigned to hmacAlgorithm to hash with SHA512.