Permalink
Browse files

First commit

  • Loading branch information...
florianheinemann committed May 10, 2014
0 parents commit c317ba7820c2974c35354806812d205bab8c8620
@@ -0,0 +1,15 @@
lib-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz

pids
logs
results

npm-debug.log
node_modules
@@ -0,0 +1,17 @@
module.exports = function(grunt) {

grunt.loadNpmTasks('grunt-mocha-test');

grunt.initConfig({
mochaTest: {
test: {
options: {
reporter: 'spec'
},
src: ['test/**/*.test.js']
}
}
});

grunt.registerTask('test', ['mochaTest']);
};
@@ -0,0 +1,11 @@
'use strict';

function AuthDataStore() {

}

AuthDataStore.prototype.authenticate = function(hashedToken, callback) {
throw new Error('AuthDataStore shall never be called in its abstract form');
}

module.exports = AuthDataStore;
@@ -0,0 +1,54 @@
'use strict';

var url = require('url');

var _dataStore = null;

module.exports = {
authenticate: function(options) {
return function(req, res, next) {
options = options || {};

if(req.query.token) {
var token = req.query.token;

if(_dataStore) {
_dataStore.authenticate(token, function(error, uid, referrer) {
if(uid) {
next();
} else if(error) {
throw new Error(error);
} else {
authenticationError();
}
});
} else {
authenticationError();
}
} else {
authenticationError();
}

function authenticationError() {
if(options.notAuthRedirect) {
var queryParam = '';
if(options.originUrlParam){
var parsedRedirectUrl = url.parse(options.notAuthRedirect), queryParam = '?';
if(parsedRedirectUrl.query) {
queryParam = '&';
}
queryParam += options.originUrlParam + '=' + encodeURIComponent(req.originalUrl);
}

res.redirect(options.notAuthRedirect + queryParam);
} else {
res.send(403);
}
}
}
},

init: function(dataStore) {
_dataStore = dataStore;
}
};
@@ -0,0 +1,11 @@
'use strict';

function Schema() {

}

Schema.prototype.sendToken = function(clearTextToken) {
throw new Error('Schema shall never be called in its abstract form');
}

module.exports = Schema;
@@ -0,0 +1,36 @@
{
"name": "passwordless",
"version": "0.0.1",
"description": "A node.js module for passwordless authentication",
"main": "index.js",
"scripts": {
"test": "grunt test"
},
"repository": {
"type": "git",
"url": "https://github.com/florianheinemann/passwordless.git"
},
"keywords": [
"node",
"nodejs",
"passwordless",
"nopassword",
"password-less",
"no-password",
"authentication"
],
"author": "Florian Heinemann <florian.heinemann@gmail.com> (http://twitter.com/florian__h)",
"license": "MIT",
"bugs": {
"url": "https://github.com/florianheinemann/passwordless/issues"
},
"homepage": "https://github.com/florianheinemann/passwordless",
"devDependencies": {
"chai": "^1.9.1",
"express": "^4.1.1",
"grunt": "^0.4.4",
"grunt-mocha-test": "^0.10.2",
"mocha": "^1.18.2",
"supertest": "^0.12.0"
}
}
@@ -0,0 +1,22 @@
'use strict';

var util = require('util');
var AuthDataStore = require('../../lib/authdatastore');

function AuthDataStoreMock() {
AuthDataStore.call(this);
}

util.inherits(AuthDataStoreMock, AuthDataStore);

AuthDataStoreMock.prototype.authenticate = function(hashedToken, callback) {
if(hashedToken === 'invalid') {
callback(null, false, null);
} else if (hashedToken === 'valid') {
callback(null, 'mail@example.com', null);
} else if(hashedToken === 'error') {
callback('Unknown error', null, null);
}
};

module.exports = AuthDataStoreMock;
@@ -0,0 +1,140 @@
'use strict';

var expect = require('chai').expect;
var express = require('express');
var request = require('supertest');
var passwordless = require('../lib');

describe('passwordless', function() {
describe('authenticate() [no authentication yet]', function() {
it('should return 403 if passwordless is not initialized - use scenario 1/3', function (done) {

var app = express();

app.get('/test', passwordless.authenticate(),
function(req, res){
res.send(200, 'authenticated');
});

request(app)
.get('/test')
.expect(403, done);
}),
it('should return 403 if passwordless is not initialized - use scenario 2/3', function (done) {

var app = express();

app.use(passwordless.authenticate());

app.get('/test',
function(req, res){
res.send(200, 'authenticated');
});

request(app)
.get('/test')
.expect(403, done);
}),
it('should return 403 if passwordless is not initialized - use scenario 3/3', function (done) {

var app = express();

app.use('/restricted', passwordless.authenticate());

app.get('/restricted/test',
function(req, res){
res.send(200, 'authenticated');
});

app.get('/everyone',
function(req, res){
res.send(200, 'authenticated');
});

request(app)
.get('/restricted/test')
.expect(403, done);


}),
it('should allow request if middleware is not in the mount path of express', function (done) {

var app = express();

app.use('/restricted', passwordless.authenticate());

app.get('/restricted/test',
function(req, res){
res.send(200, 'authenticated');
});

app.get('/everyone',
function(req, res){
res.send(200, 'authenticated');
});

request(app)
.get('/everyone')
.expect(200, done);
}),
it('should redirect to the given URL if "notAuthRedirect" is provided and user not authorized', function (done) {

var app = express();

app.get('/test', passwordless.authenticate({ notAuthRedirect: '/login' }),
function(req, res){
res.send(200, 'authenticated');
});

request(app)
.get('/test')
.expect(302)
.expect('location', '/login', done);
}),
it('should redirect and pass the original URL if not authorized if "originUrlParam" is provided / simple', function (done) {

var app = express();

app.get('/test', passwordless.authenticate({ notAuthRedirect: '/login',
originUrlParam: 'origin' }),
function(req, res){
res.send(200, 'authenticated');
});

request(app)
.get('/test?id=3')
.expect(302)
.expect('location', '/login?origin=%2Ftest%3Fid%3D3', done);
}),
it('should redirect and pass the original URL if not authorized if "originUrlParam" is provided / additional param', function (done) {

var app = express();

app.get('/test', passwordless.authenticate({ notAuthRedirect: '/login?mode=test&lang=en',
originUrlParam: 'origin' }),
function(req, res){
res.send(200, 'authenticated');
});

request(app)
.get('/test?id=3')
.expect(302)
.expect('location', '/login?mode=test&lang=en&origin=%2Ftest%3Fid%3D3', done);
}),
it('should flash a message if user is not authorized and "flashMessage" is set to true', function (done) {

var app = express();

app.get('/protected', passwordless.authenticate({ notAuthRedirect: '/login',
flashMessage: true }),
function(req, res){
res.send(200, 'authenticated');
});

request(app)
.get('/protected')
.expect(302)
expect('location', '/login', done('should flash a message saying that user is not authorized'));
})
})
});
Oops, something went wrong.

0 comments on commit c317ba7

Please sign in to comment.