From cce8d9e3600e8ba0ced12013b0b208fff9f9c8a8 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 12 Oct 2016 20:03:14 -0700 Subject: [PATCH] Began adding browser-native encryptor module Added new Qunit build process that will browserify the contents of `test/integration/lib` into the QUnit browser, allowing much more modular testing, including unit testing of our modules in our target browsers. Made a basic unit test file of this form for the new encryptor module, which fails miserably because I've only just begun to work with it. I've started with this blog post as a starting point, and will be adjusting it to our needs from there: http://qnimate.com/passphrase-based-encryption-using-web-cryptography-api/ --- README.md | 4 + app/scripts/lib/encryptor.js | 51 +++++++++ package.json | 3 +- test/integration/bundle.js | 103 ++++++++++++++++++ test/integration/index.html | 2 +- test/integration/index.js | 21 ++++ test/integration/lib/encryptor-test.js | 17 +++ .../{tests.js => lib/first-time.js} | 3 +- 8 files changed, 201 insertions(+), 3 deletions(-) create mode 100644 app/scripts/lib/encryptor.js create mode 100644 test/integration/bundle.js create mode 100644 test/integration/index.js create mode 100644 test/integration/lib/encryptor-test.js rename test/integration/{tests.js => lib/first-time.js} (88%) diff --git a/README.md b/README.md index afdda4d97..09fb0079c 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,10 @@ You can also test with a continuously watching process, via `npm run watch`. You can run the linter by itself with `gulp lint`. +#### Writing Browser Tests + +To write tests that will be run in the browser using QUnit, add your test files to `test/integration/lib`. + ### Deploying the UI You must be authorized already on the MetaMask plugin. diff --git a/app/scripts/lib/encryptor.js b/app/scripts/lib/encryptor.js new file mode 100644 index 000000000..607825764 --- /dev/null +++ b/app/scripts/lib/encryptor.js @@ -0,0 +1,51 @@ +var vector = global.crypto.getRandomValues(new Uint8Array(16)) +var key = null + +module.exports = { + encrypt, + decrypt, + convertArrayBufferViewtoString, + keyFromPassword, +} + +// Takes a Pojo, returns encrypted text. +function encrypt (password, dataObj) { + var data = JSON.stringify(dataObj) + global.crypto.subtle.encrypt({name: 'AES-CBC', iv: vector}, key, convertStringToArrayBufferView(data)).then(function(result){ + const encryptedData = new Uint8Array(result) + return encryptedData + }, + function(e){ + console.log(e.message) + }) +} + +// Takes encrypted text, returns the restored Pojo. +function decrypt (password, text) { + +} + +function convertStringToArrayBufferView (str) { + var bytes = new Uint8Array(str.length) + for (var i = 0; i < str.length; i++) { + bytes[i] = str.charCodeAt(i) + } + + return bytes +} + +function convertArrayBufferViewtoString (buffer) { + var str = '' + for (var i = 0; i < buffer.byteLength; i++) { + str += String.fromCharCode(buffer[i]) + } + + return str +} + +function keyFromPassword (password) { + global.crypto.subtle.digest({name: 'SHA-256'}, convertStringToArrayBufferView(password)).then(function(result){ + return global.crypto.subtle.importKey('raw', result, {name: 'AES-CBC'}, false, ['encrypt', 'decrypt']) + }) +} + diff --git a/package.json b/package.json index 273117f8a..a4f234735 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "lint": "gulp lint", "dev": "gulp dev", "dist": "gulp dist", + "buildCiUnits": "node test/integration/index.js", "test": "npm run fastTest && npm run ci && npm run lint", "fastTest": "mocha --require test/helper.js --compilers js:babel-register --recursive \"test/unit/**/*.js\"", "watch": "mocha watch --compilers js:babel-register --recursive \"test/unit/**/*.js\"", @@ -15,7 +16,7 @@ "mock": "beefy mock-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./", "buildMock": "browserify ./mock-dev.js -o ./development/bundle.js", "testem": "npm run buildMock && testem", - "ci": "npm run buildMock && testem ci -P 2", + "ci": "npm run buildMock && npm run buildCiUnits && testem ci -P 2", "announce": "node development/announcer.js" }, "browserify": { diff --git a/test/integration/bundle.js b/test/integration/bundle.js new file mode 100644 index 000000000..5058259b1 --- /dev/null +++ b/test/integration/bundle.js @@ -0,0 +1,103 @@ +window.QUnit = QUnit; (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o - +