We've got Crypto, shhhhhh

AeroGear.js 1.3.0 has just been released. This release saw some very cool and very important features get added to the library as well as various bug fixes and general improvements. Lets checkout some of the major players in this release.

Crypto

With this release we started to lay down the groundwork for encryption using already existent libraries since it would be a shame to reinvent the wheel.

Basically our focus was to create a simple API for humans to make use of these encryption functionalities:

  • symmetric encryption with GCM
  • digital signatures
  • asymmetric encryption with elliptic curves
  • PBKDF2

We’ve been told that JavaScript cryptography can be considered harmful and that there’s some already known issues, but we are true believers that the WebCrypto specification will help us to provide better cryptography to our applications.

You are free to strongly disagree and help us to improve.

example

Here is a small example from our unit tests

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var rawPassword = AeroGear.Crypto().deriveKey( PASSWORD ),
utf8String = sjcl.codec.utf8String,
hex = sjcl.codec.hex,
cipherText,
options = {
IV: hex.toBits( BOB_IV ),
AAD: hex.toBits( BOB_AAD ),
key: rawPassword,
data: utf8String.toBits( PLAIN_TEXT )
};

cipherText = AeroGear.Crypto().encrypt( options );
options.data = cipherText;
plainText = AeroGear.Crypto().decrypt ( options );
equal( utf8String.fromBits( plainText ), PLAIN_TEXT, "Encryption has failed" );

Note: to learn more check out all our Crypto Unit Tests here

DataManager

New Adapters

Datamanager got a lot of love this release. 2 new adapters, WebSQL and IndexedDB, have been added.

That brings your choices of adapters to 4( 5 if you count session and local as seperate ones ).

And since these 2 new adapters are Asynchronous in nature, I’m pleased to announce that all previous adapters now have aynchronous API’s. You also have your choice of using promises or just regular callbacks.

note: The Synchronous API for the Memory and SessionLocal adapters will be synchronous by default but are now deprecated and will be removed in the 1.4.0 release

example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Create an Empty DataManager
var dm = AeroGear.DataManager(),
idb;

// Add an IndexedDB store
dm.add( { name: "idb", type: "IndexedDB" } );

idb = dm.stores.idb;

// First we must open the IndexedDB store
idb.open().then( function() {
// Here we are using a promise to notify us of the finished async operation

// To read all data in the store
idb.read().then( function( data ) {
console.log( data );
});
});

All the methods that you are already use like save, read, and remove are the same.

Fallbacks

“But what happens in IE9 with these new adapters?” I’m glad you asked.

Another enhancement that DataManager recieved was Fallbacks

So, for example, you create an IndexedDB store and a browser doesn’t support it, like Safari, the store will fallback to something that is supported( In this example, WebSQL ).

example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Create an Empty DataManager
var dm = AeroGear.DataManager(),
idb;

// Add an IndexedDB store, which will fallback to WebSQL
dm.add( { name: "idb", type: "IndexedDB" } );

idb = dm.stores.idb;

// First we must open the IndexedDB store
idb.open().then( function() {
// Here we are using a promise to notify us of the finished async operation

// To read all data in the store
idb.read().then( function( data ) {
console.log( data );
});
});


// To check that it fellback to WebSQL
if( idb instanceof AeroGear.DataManager.adapters.WebSQL) {
console.log( true );
}

You should notice that there was no code changes, the API’s are the same.

Encrypted Stores

With the announcement of AeroGear.js getting Crypto, you can now add Crypto to a Store.

note: the Memory store does not currently support encryption

example

Using the same example as above

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Create an Empty DataManager
var dm = AeroGear.DataManager(),
// Create a new Crypto object to use
agcrytpo = AeroGear.Crypto();
idb;

// Add an IndexedDB store
dm.add({
name: "idb",
type: "IndexedDB",
settings: {
// New crypto options for DataManager
crypto: {
agcrypto: agcrypto,
options: {
key: "password"
}
}
}
});

idb = dm.stores.idb;

...

// To read all data in the store
idb.save( data ).then( function( data ) {
// Now when we save the data, it will be encrypted then stored in our IndexedDB store
// And on .read(), the data will be decrypted
});

...

To verify that your data is being encrypted, you can you Chrome Dev Tools or similiar to inspect your resources

Pipeline

MultiPart Uploads

Pipeline saw a small but welcome addition to feature set, MultiPart Uploads

It is now possible to easily upload a file right from a pipe.

example

Here we have a form with an input type of file. We also have a HTML5 progress element

1
2
3
4
5
6
<form>
<input name="file" type="file" />
<input type="button" value="Upload" />
</form>

<progress id="pp" value="0"></progress>

And in our Javascript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Create the pipeline
var pipeline = AeroGear.Pipeline();

// Add a pipe
var filepip = pipeline.add({
name: "filepipe"
}).pipes.filepipe;

// Assume jQuery
$(':button').click(function(){
// Get the file from the input and store it in our JSON object
var formData = {
file: $("input[type='file']")[0].files[0]
};

// Call the save method on the pipe with the data
filepip.save( formData, {
success: function(){
console.log( "success", arguments );
},
error: function() {
console.log( "error", arguments );
},
// Also listening for progress events on the upload if your browser supports it
progress: function( event ) {
console.log( "progress", arguments );
// Updates the progress element
$( "#pp" ).attr( "value", event.position );
$( "#pp" ).attr( "max", event.totalSize );
}
});
});

So as you can see, if you are already using AeroGear.Pipeline, you can now start taking advantage of easily uploading files with the rest of your data

Code

As always, you can view the source code here

If bower is your thing:

$ bower install aerogear

Or if you want to create a custom build, JS Custom Builder

Release Notes - AeroGear JavaScript - Version 1.3.0

Bug

  • [AGJS-75] - undefined pipe created
  • [AGJS-76] - Multiple ways to set a recordId is causing issues
  • [AGJS-84] - Pipeline REST adapter save/update does not send data
  • [AGJS-96] - deriveKey in crypto-js generates same bits every time

Feature Request

  • [AGJS-5] - Provide a encryption method to protect secrets
  • [AGJS-6] - IndexedDB Adapter
  • [AGJS-7] - WebSQL Adapter
  • [AGJS-16] - JS: Enable Multipart uploads on AG JS
  • [AGJS-18] - Add HTTP basic authentication support on AeroGear.js
  • [AGJS-23] - Add HTTP digest authentication support on AeroGear.js
  • [AGJS-69] - Accept success/error/complete callback on the unifiedPushClient.registerWithPushServer function
  • [AGJS-73] - Add OTP Adapter
  • [AGJS-78] - Provide an interface for symmetric encryption into AeroGear.js
  • [AGJS-79] - Provide an interface for password encryption into AeroGear.js
  • [AGJS-80] - Add xhrFields option for Pipe and Auth Rest adapters
  • [AGJS-81] - Provide an interface for hashing into AeroGear.js
  • [AGJS-82] - Provide an interface for digital signatures into AeroGear.js
  • [AGJS-83] - Provide an interface for asymmetric encryption into AeroGear.js
  • [AGJS-86] - Fallback Strategy for DataManager Adapters
  • [AGJS-90] - Deprecate DataManager Synchronous API
  • [AGJS-91] - Support registration for multiple categories
  • [AGJS-92] - Do not submit device token on DELETE request
  • [AGJS-94] - Provide an interface and examples for password based encryption
  • [AGJS-97] - Add crypto support to AGJS datamanager
  • [AGJS-98] - Store the user's salt on encrypted datamanagers

Task

  • [AGJS-42] - Remove jQuery dependency from DataManager
  • [AGJS-46] - Make it so everyone can run the JS docs
  • [AGJS-66] - Remove "mobile" from custom builder download file name
  • [AGJS-74] - Move Authentication setting to the Pipeline level
  • [AGJS-88] - Refactor DataManager Unit Tests