Skip to content

Commit

Permalink
Added gulp tasks for release process.
Browse files Browse the repository at this point in the history
- Includes commands to build and release browser builds
- Commands to run node and browser tests with karma
  • Loading branch information
Braydon Fuller committed Sep 18, 2015
1 parent 452dc53 commit 66a3dbb
Show file tree
Hide file tree
Showing 14 changed files with 284 additions and 50 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
node_modules
bitauth.js
bitauth.min.js
tests.js


2 changes: 1 addition & 1 deletion .jshintrc
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"maxlen": 120,
"multistr": true,

"predef": [ // Extra globals.
"predef": [
"after",
"afterEach",
"before",
Expand Down
10 changes: 9 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
language: node_js
sudo: false
node_js:
- '0.10'
- '0.10'
- '0.12'
before_install:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
install:
- npm install


41 changes: 19 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@ npm install bitauth
To generate a browser bundle, you can then run:

```bash
npm run make-dist
gulp browser
```


## Advantages over other authentication mechanisms

* By signing each request, man in the middle attacks are impossible.
Expand All @@ -38,18 +37,18 @@ in HMAC.

## Technical Overview
BitAuth uses the same technology in Bitcoin. A public private key pair is created
using elliptic curve secp256k1. The public SIN (System identification number),
like a bitcoin address, is the RIPEMD 160, SHA256 hash of the public key.
using elliptic curve secp256k1. The public SIN (System identification number),
like a bitcoin address, is the RIPEMD 160, SHA256 hash of the public key.
See https://en.bitcoin.it/wiki/Identity_protocol_v1 for complete details.

In each request, the client includes a nonce to prevent replay attacks. The client
signs the full url with the request body concatenated if there is one. The signature
is included in the `x-signature` header and the public key is included in the
signs the full url with the request body concatenated if there is one. The signature
is included in the `x-signature` header and the public key is included in the
`x-identity` header.

The server verifies that the signature is valid and that it matches the identity (the public key).
It then computes the SIN from the public key, and sees whether that SIN has access
to the requested resource. The nonce is checked to make sure it is higher than
to the requested resource. The nonce is checked to make sure it is higher than
the previously used nonce.

## Technology is readily available
Expand All @@ -62,7 +61,7 @@ to start using BitAuth.
## Problems with password authentication

* Have to keep track of a separate password for every web service. People forget
passwords, encouraging them to reuse passwords and opening themselves up to
passwords, encouraging them to reuse passwords and opening themselves up to
having multiple services compromised.
* Brute force attacks on weak passwords.
* Passwords may travel over plaintext
Expand All @@ -76,16 +75,16 @@ not worry about one service gaining access to another.

In the future, an identity system could be built around BitAuth keys where a user
could create one key to represent an identity which could authenticate against
multiple services.
multiple services.

In order for this to work, there would have to be a browser
integration or plugin which would manage these identities and a Javascript API
where websites could sign requests going to their website with the private key,
In order for this to work, there would have to be a browser
integration or plugin which would manage these identities and a Javascript API
where websites could sign requests going to their website with the private key,
but without exposing the private key to the third party sites.

There also needs to be a public place to store SIN's, preferably in
a decentralized blockchain or datastore like namecoin. Key revocations could
be stored here as well as reviews/feedback to build a reputation around an
a decentralized blockchain or datastore like namecoin. Key revocations could
be stored here as well as reviews/feedback to build a reputation around an
identity.

## Examples
Expand Down Expand Up @@ -188,7 +187,7 @@ for(k in keys) {
}
if(body) {
console.log(body);
}
}
});
}

Expand All @@ -206,21 +205,19 @@ app.use( bitauth.middleware );
To build a browser compatible version of BitAuth, run the following command from the project's root directory:

```bash
npm run make-dist
gulp browser
```

This will output `bitauth.browser.min.js` to the `dist` directory. The script introduces a global variable at `window.bitauth`.

This will output `bitauth.min.js` to project directory. The script can be loaded using `require('bitauth')`.

To then run tests for a web browser open `test/index.html` in a browser, such as:
To then run tests for a web browser:

```bash
firefox test/index.html
chromium-browser test/index.html
gulp test:browser
```

To run tests for Node.js:

```bash
npm run test
gulp test:node
```
29 changes: 29 additions & 0 deletions bower.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "bitauth",
"main": "./bitauth.min.js",
"version": "0.2.1",
"homepage": "https://github.com/bitpay/bitauth",
"authors": [
"BitPay, Inc."
],
"description": "Passwordless authentication using Bitcoin cryptography",
"moduleType": [
"globals"
],
"keywords": [
"bitcoin",
"bitcore",
"btc",
"satoshi"
],
"license": "MIT",
"ignore": [
"**/.*",
"CONTRIBUTING.md",
"gulpfile.js",
"lib",
"index.js",
"karma.conf.js",
"test"
]
}
3 changes: 0 additions & 3 deletions dist/.gitignore

This file was deleted.

176 changes: 176 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
'use strict';

// Run these commands to make a release:
//
// gulp release:checkout-releases
// gulp release:install
// gulp test
// gulp release:bump:<major|minor|patch>
// gulp browser
// gulp release:build-commit
// gulp release:push-tag
// npm publish
// gulp release:checkout-master
// gulp release:bump:<major|minor|patch>
// gulp release:version-commit
// gulp release:push

var path = require('path');
var gulp = require('gulp');
var shell = require('gulp-shell');
var mocha = require('gulp-mocha');
var runsequence = require('run-sequence');
runsequence.use(gulp);
var bump = require('gulp-bump');
var git = require('gulp-git');

var binPath = path.resolve(__dirname, './node_modules/.bin/');
var browserifyPath = path.resolve(binPath, './browserify');
var uglifyPath = path.resolve(binPath, './uglifyjs');
var indexPath = path.resolve(__dirname, './lib/bitauth-browserify');
var namePath = path.resolve(__dirname, './bitauth');
var bundlePath = namePath + '.js';
var minPath = namePath + '.min.js';

var browserifyCommand = browserifyPath + ' --require ' + indexPath + ':bitauth -o ' + bundlePath;
var uglifyCommand = uglifyPath + ' ' + bundlePath + ' --compress --mangle -o ' + minPath;

gulp.task('browser:uncompressed', shell.task([
browserifyCommand
]));

gulp.task('browser:compressed', ['browser:uncompressed'], shell.task([
uglifyCommand
]));

gulp.task('browser:maketests', shell.task([
'find test/ -type f -name "*.js" | xargs ' + browserifyPath + ' -o tests.js'
]));

gulp.task('browser', function(callback) {
runsequence(['browser:compressed'], callback);
});


gulp.task('release:install', function() {
return shell.task([
'npm install',
]);
});

var releaseFiles = ['./package.json', './bower.json'];

var bumpVersion = function(importance) {
return gulp.src(releaseFiles)
.pipe(bump({
type: importance
}))
.pipe(gulp.dest('./'));
};

['patch', 'minor', 'major'].forEach(function(importance) {
gulp.task('release:bump:' + importance, function() {
bumpVersion(importance);
});
});

gulp.task('release:checkout-releases', function(cb) {
var tempBranch = 'releases/' + new Date().getTime() + '-build';
git.branch(tempBranch, {
args: ''
}, function() {
git.checkout(tempBranch, {
args: ''
}, cb);
});
});

gulp.task('release:checkout-master', function(cb) {
git.checkout('master', {
args: ''
}, cb);
});

gulp.task('release:sign-built-files', shell.task([
'gpg --yes --out ' + namePath + '.js.sig --detach-sig ' + namePath + '.js',
'gpg --yes --out ' + namePath + '.min.js.sig --detach-sig ' + namePath + '.min.js'
]));

var buildFiles = ['./package.json'];
var signatureFiles = [];
buildFiles.push(namePath + '.js');
buildFiles.push(namePath + '.js.sig');
buildFiles.push(namePath + '.min.js');
buildFiles.push(namePath + '.min.js.sig');
buildFiles.push('./bower.json');
signatureFiles.push(namePath + '.js.sig');
signatureFiles.push(namePath + '.min.js.sig');

var addFiles = function() {
return gulp.src(buildFiles)
.pipe(git.add({
args: '-f'
}));
};

var buildCommit = function() {
var pjson = require('./package.json');
return gulp.src(buildFiles)
.pipe(git.commit('Build: ' + pjson.version, {
args: ''
}));
};

gulp.task('release:add-signed-files', ['release:sign-built-files'], addFiles);
gulp.task('release:add-built-files', addFiles);
gulp.task('release:build-commit', [
'release:add-signed-files'
], buildCommit);

gulp.task('release:version-commit', function() {
var pjson = require('./package.json');
return gulp.src(releaseFiles)
.pipe(git.commit('Bump package version to ' + pjson.version, {
args: ''
}));
});

gulp.task('release:push', function(cb) {
git.push('upstream', 'master', {
args: ''
}, cb);
});

gulp.task('release:push-tag', function(cb) {
var pjson = require('./package.json');
var name = 'v' + pjson.version;
git.tag(name, 'Release ' + name, function() {
git.push('upstream', name, cb);
});
});

gulp.task('release:publish', shell.task([
'npm publish'
]));

var tests = ['test/**/*.js'];
var testmocha = function() {
return gulp.src(tests).pipe(new mocha({
recursive: true
}));
};
var testkarma = shell.task([
path.resolve(__dirname, './node_modules/karma/bin/karma') +
' start ' + path.resolve(__dirname, './karma.conf.js')
]);

gulp.task('test:node', testmocha);
gulp.task('test:browser', ['browser:uncompressed', 'browser:maketests'], testkarma);

gulp.task('test', function(callback) {
runsequence(['test:node'], ['test:browser'], callback);
});

gulp.task('benchmark', shell.task([
'node benchmarks/index.js'
]));
18 changes: 12 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
// get base functionality
var bitauth = require('./lib/bitauth-node');
'use strict';

// add node-specific encrypt/decrypt
bitauth.encrypt = require('./lib/encrypt');
bitauth.decrypt = require('./lib/decrypt');
bitauth.middleware = require('./lib/middleware/bitauth');
var bitauth;
if (process.browser) {
bitauth = require('./lib/bitauth-browserify');
} else {
bitauth = require('./lib/bitauth-node');

// add node-specific encrypt/decrypt
bitauth.encrypt = require('./lib/encrypt');
bitauth.decrypt = require('./lib/decrypt');
bitauth.middleware = require('./lib/middleware/bitauth');
}

module.exports = bitauth;
18 changes: 18 additions & 0 deletions karma.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';

module.exports = function(config) {

config.set({
browsers: ['Firefox'],
frameworks: ['mocha'],
singleRun: true,
files: [
'./tests.js'
],
plugins: [
'karma-mocha',
'karma-firefox-launcher'
]
});

};
2 changes: 1 addition & 1 deletion lib/bitauth-common.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ BitAuth.PREFIX = new Buffer('0f02', 'hex');
*/
BitAuth.generateSin = function() {
var pair = BitAuth._generateRandomPair();
var sin = this.getSinFromPublicKey(pair[1]);
var sin = BitAuth.getSinFromPublicKey(pair[1]);
var sinObj = {
created: Math.round(Date.now() / 1000),
priv: pair[0],
Expand Down
Loading

0 comments on commit 66a3dbb

Please sign in to comment.