Skip to content

Commit

Permalink
tested
Browse files Browse the repository at this point in the history
  • Loading branch information
justincy committed Nov 17, 2015
1 parent 775036c commit 6c3c580
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 20 deletions.
30 changes: 30 additions & 0 deletions key.pem
@@ -0,0 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,78E62ACC722BE51C

+1SVVvnHtBE0oJuJX3JFntEOrsg5AdSUNjWXSHQvOMfbufuNn7pIRzNzmrSSHoB5
oFk7qdWaVaZn8EYR5j43eJEC+BuULtRnXMDbMLFivr3cDGJFs3C/jvfvlCjFQpd6
GuMBgf7XR2gRrGcbF139pQHNqxHViIfNa+b5/YARtakyfxmzph1Ffnlp5x/59jQv
9J42xUt0pwDaE1v8s30++9Z160nfFeZ7wVQfdnOg3y5Fz/D87r1vN7j2c4VLCvev
pBW0iVbmJOgQ8zcHhP72AN7EvCEiyu4ar/0n23Gcm5XDmSFaOBXXzbELUEoSADoL
Wj6qpqn1Up9R3qUUymJ0EBj2b3noYPS6VVfck3VjkWRP5qd1ziyE0Fi7LFKoQi9D
CzW/aca+tXEMipvKFKXBx4eerNhHZD64Jy2/Ip9CTox9/tRP437XhLlEDCGBmROd
1LV5RN/uDwTpjf9fSHeNnKC4W/hAfKQkU2kQ3jvuCsB0vPM6luaR6SYuH3kWS5jA
mIO1xYIrNURDEIwwR6SfXD5XE/k0yG5YT8CZZ41m+GG7qK1zLJezn0WoIvb/DAN/
KnAQQTWfFfwbC4Eejr040B55w2WzpMGMp2g2HbAA+qxEQ9eaCRHc0TquRC97lgwi
o6h69YgutqnYCLUZDtoL3nsKeE+ad3Qclux+duAWZp2+V7fZvDLPgRwmoaAV7yJf
oawFYnNzKKo4Ssst2CX+YkUCINXeHlJiFqW1IbIa/e8cpD4rOcGq03IfVXfd+NL4
EmN/BAloRRmfZO9CfRkcprEXsnLUFq/udzPxVzbw5H2fkraHeLWOILOOjZdV2O7F
lDpnI6a7qGM8IsI5T6JfZs0zeSeUboAbCouvvts0jkBowQSzplW8iNUhWpXcCvMQ
947EcuqGKtaxHHECTcDhsZuWwu1cYlwtq8gw1IoJw1b/qOWetRqzEy1/2EKJ0TeH
Rpg1yorAAhepfvNp1sAqh/x8T0qONg6U4atTDy77o4ZmpJcZ8B3PpTp1QdqWyYCi
nd7hVHHoe1a0IopNkzSUp/YgBleK1GPlKwjbGASRQUhnhwiFWHAIGA/pbG6qrlUE
iMvz9N1UM25i2WeAtosCeKanIU/ujzfSss6GzYc07Y/TQX1K9Qp4u/wehDUfiBbi
4l1rOhRc2WdO9t+BP8TSSbu8YXaeq5D0GWxa5N0cuzSBis6WqiZ13LBBywfzQI/V
EH72KKc1GLWmcXO4iMeG3M4hohKM6OfhAvLEa7irFjVZi9Y6fErgtLEywkjQnSQU
uwdtp4Wc3A+bJKH2YxTJBTQYtckQ5YGiJsWGicV4flyxvkMHrsGISxYa6uXpSvAx
UcwXHQhWOlfT5KFxNTYCyBKkg7t2pDr5P7aYa4rB8eO/Qz0ToDgmbVGD4fQygRLT
NUGtGCkjA+SDnJ0HF+g4m4kh8z6xA17rWCJFaVajidBSoffutTWwbPWLoKZ2dwKa
C/0zBM6jPIwjSZNQ79EVoukaOgny1TC1NzZbiJlIiYhJYfuUJz2j3S1LKyQUaIgl
7j+9BWNS9LgOLVdNeEzVPJIXphlf5s1bdSdJ51M7FXszh4tO1wIP9A3DWzDXCM/Z
-----END RSA PRIVATE KEY-----
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -43,6 +43,7 @@
},
"dependencies": {
"es6-promise": "3.0.2",
"isomorphic-fetch": "2.1.1"
"isomorphic-fetch": "2.1.1",
"ursa": "^0.9.1"
}
}
27 changes: 11 additions & 16 deletions src/modules/node-only.js
@@ -1,5 +1,5 @@
var FS = require('./../FamilySearch'),
crypto = require('crypto');
ursa = require('ursa');

/**
* Methods that are only supported in node.
Expand All @@ -10,35 +10,30 @@ var FS = require('./../FamilySearch'),
* @name authentication.functions:getAccessTokenWithClientCredentials
*
* @description
* Get an access token via client credentials. This is only supported in node
* versions >= 0.12. This will throw an exception when using in the browser or
* node versions that do not have the `crypto.privateEncrypt()` function.
* Get an access token via client credentials.
*
* @param {String} key The `private_key` value of [crypto.privateEncrypt()](https://nodejs.org/api/crypto.html#crypto_crypto_privateencrypt_private_key_buffer)
* @param {Integer|String} time This parameter is only available for the sake of testing.
* @param {String} key A PEM-encoded key. Matches the `pem` parameter of [ursa.createPrivateKey()](https://github.com/quartzjer/ursa#ursacreateprivatekeypem-password-encoding).
* @param {String=} password The password for descrypting the key, if necessary.
* @param {Integer=|String=} time This parameter is only available for the sake of testing. Do not use it in production.
*/
FS.prototype.getAccessTokenWithClientCredentials = function(key, time){

if(!crypto.privateEncrypt){
throw new Error('Authentication via client credentials is not supported in the browser and requires node version 0.12 or greater.');
}
FS.prototype.getAccessTokenWithClientCredentials = function(key, password, time){

var self = this,

// URSA key object
ukey = ursa.createPrivateKey(key, password),

// Get a timestamp in milliseconds
timestamp = time || Date.now(),

// Encrypt the timestamp using the private key
secret = crypto.privateEncrypt(key, new Buffer(timestamp + '')),

// Encode the secret into base64
encodedSecret = new Buffer(secret).toString('base64');
secret = ukey.privateEncrypt(timestamp + '', 'utf8', 'base64');

// Make the request
return self.plumbing.post(self.settings.oauthServer[self.settings.environment] + '/token', {
'grant_type': 'client_credentials',
'client_id': self.settings.clientId,
'client_secret': encodedSecret
'client_secret': secret
},
// access token endpoint says it accepts json but it doesn't
{'Content-Type': 'application/x-www-form-urlencoded'}).then(function(response){
Expand Down
10 changes: 7 additions & 3 deletions test/unit/authenticationSpec.js
@@ -1,4 +1,5 @@
var url = require('url');
var querystring = require('querystring'),
fs = require('fs');

describe('An access token', function() {

Expand Down Expand Up @@ -29,8 +30,11 @@ describe('An access token', function() {

it('is returned from getAccessTokenWithClientCredentials', function(done){
FS.invalidateAccessToken().then(function(){
FS.getAccessTokenWithClientCredentials(process.env['FS_CLIENT_KEY'], 12345).then(function(accessToken){
expect(url.parse(__getHttpRequests()[0].url, true)['client_secret']).toBe('foo');
FS.getAccessTokenWithClientCredentials(fs.readFileSync('key.pem'), process.env['FS_KEY_PASSWORD'], 1447773012436).then(function(accessToken){
var request = __getHttpRequests()[3],
body = request.body,
params = querystring.parse(body);
expect(params['client_secret']).toBe('vAo5bmjV2SZj9XCZJ5HAew6bFwrz1uuPyyQMfjlAddoELBKkZdTsaua7iK6J0AZPu9vo8Nzd/Nc/r1UHiSVR0N4N5q8DX8p5jDe+/LRzwyog1tS6zW/ke8S/x+eSNtbMhXAsHixMJkwrncMgmhoqEYX99Glh4wc4CNVU+eSB8seBDG37KTlUsEK//gm+vbt2/v6A3U4CEp7BTPMIGNWoWm0548zzO01cnZ2zezXMuwDARH0ENy3gQ37sG2tI+9MBHijO7Q8TG+4GfbVzz/QOQuDDL/rf9MonZcFF+pdaESDk7NpRGeXKGfCpHHHHQF7Eyobisdrl35WGowdCwnUzew==');
expect(accessToken).toBe('2YoTnFdFEjr1zCsicMWpAA');
done();
});
Expand Down
10 changes: 10 additions & 0 deletions test/unit/helpers.js
Expand Up @@ -70,6 +70,16 @@ function loadFile(filename){
* @param opts
*/
function httpMock(req, res) {

// Make the request body available to tests
var body = '';
req.on('data', function(data){
body += data;
});
req.on('end', function(){
req.body = body;
});

requests.push(req);

var filename = getFilename(req);
Expand Down

0 comments on commit 6c3c580

Please sign in to comment.