Skip to content

Instantly share code, notes, and snippets.

@yemel
Last active August 29, 2015 13:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yemel/10114496 to your computer and use it in GitHub Desktop.
Save yemel/10114496 to your computer and use it in GitHub Desktop.
"use strict";
var pg = require('pg');
var crypto = require('crypto');
var DATABASE_URL = process.env.DATABASE_URL;
// -------- Cryptographic functions --------
// Passwords are represented as SALT:SHA1_HASH in base64.
var KEYLEN = 32;
var ITERATIONS = 10000;
var SALT_BYTES = 10;
function digestPassword(password, salt, callback) {
// Salt is an optional parameter
if (salt instanceof Function) {
callback = salt;
salt = crypto.randomBytes(SALT_BYTES).toString('base64');
}
crypto.pbkdf2(password, salt, ITERATIONS, KEYLEN, function onHash(err, key) {
var hash = new Buffer(key).toString('base64');
callback(salt + ':' + hash);
});
}
function checkPassword(password, digest, callback) {
var data = digest.split(':');
digestPassword(password, data[0], function onDigest(ndigest) {
callback(ndigest === digest);
});
}
// -------- Database functions --------
function purgeDatabase(callback) {
var client = new pg.Client(DATABASE_URL);
client.connect(function onConnection(err) {
client.query('DELETE FROM core_user', onDelete);
});
function onDelete(err, result) {
client.end();
callback();
}
}
function addUser(username, password, callback) {
if (username === undefined || password === undefined) {
return console.error('Invalid username or password');
}
var client = new pg.Client(DATABASE_URL);
client.connect(function onConnection(err) {
var query = 'SELECT * FROM core_user WHERE username LIKE $1';
client.query(query, [username], onSelect);
});
function onSelect(err, result) {
if (result.rows.length !== 0) {
return console.error('username already exists');
}
digestPassword(password, function onDigest(digest){
var query = 'INSERT INTO core_user(username, password) VALUES ($1, $2)';
client.query(query, [username, digest], onInsert);
});
}
function onInsert(err, result) {
client.end();
callback();
}
}
function authenticateUser(username, password, callback) {
var client = new pg.Client(DATABASE_URL);
client.connect(function onConnection(err) {
var query = 'SELECT * FROM core_user WHERE username LIKE $1';
client.query(query, [username], onResult);
});
function onResult(err, result) {
if (result.rows.length === 0) {
return callback(false);
}
checkPassword(password, result.rows[0].password, callback);
}
}
exports.addUser = addUser;
exports.authenticateUser = authenticateUser;
exports.purgeDatabase = purgeDatabase;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment