opentok-token
Advanced tools
Comparing version 1.0.0 to 1.1.0
47
index.js
var crypto = require('crypto'); | ||
var querystring = require('querystring'); | ||
var timestamp = require('unix-timestamp'); | ||
var nonce = require('nonce')(); | ||
var _ = require('lodash'); | ||
/** | ||
* @constant {string} | ||
* @private | ||
*/ | ||
@@ -10,15 +14,19 @@ var TOKEN_SENTINEL = 'T1=='; | ||
/** | ||
* @typedef TokenData | ||
* @type {object} | ||
* @property {string} session_id An OpenTok Session ID | ||
* @property {number} create_time Creation time of token as unix timestamp (now) | ||
* @property {number} expire_time Expiration time of token as unix timestamp | ||
* @property {number} nonce Arbitrary number used only once in a cryptographic communication | ||
* @property {string} role "publisher" or "subscriber" "moderator" | ||
* @property {string} connection_data Arbitrary data to be made available in clients on the OpenTok Connection | ||
* @typedef {Object} TokenData | ||
* @property {string} [session_id] An OpenTok Session ID | ||
* @property {number} [create_time] Creation time of token as unix timestamp (Default: now) | ||
* @property {number} [expire_time] Expiration time of token as unix timestamp (Default: one day | ||
* from now) | ||
* @property {number} [nonce] Arbitrary number used only once in a cryptographic communication | ||
* (Default: unique random number) | ||
* @property {string} [role='publisher'] "publisher" or "subscriber" "moderator" | ||
* @property {string} [connection_data] Arbitrary data to be made available in clients on the OpenTok Connection | ||
*/ | ||
/** | ||
* Encodes data for use as a token that can be used as the X-TB-TOKEN-AUTH header value in OpenTok REST APIs | ||
* | ||
* @exports opentok-token | ||
* | ||
* @param {TokenData} tokenData | ||
@@ -31,2 +39,13 @@ * @param {string} apiKey An OpenTok API Key | ||
var encodeToken = function(tokenData, apiKey, apiSecret) { | ||
// Prevent mutating value passed in | ||
tokenData = _.clone(tokenData); | ||
_.defaults(tokenData, { | ||
create_time: Math.round(timestamp.now()), | ||
expire_time: Math.round(timestamp.now('1d')), | ||
nonce: nonce(), | ||
role: 'publisher' | ||
}); | ||
var dataString = querystring.stringify(tokenData), | ||
@@ -38,2 +57,13 @@ sig = signString(dataString, apiSecret), | ||
/** | ||
* Creates an HMAC-SHA1 signature of unsigned data using the key | ||
* | ||
* @private | ||
* | ||
* @param {string} unsigned Data to be signed | ||
* @param {string} key Key to sign data with | ||
* | ||
* @returns {string} signature | ||
*/ | ||
var signString = function(unsigned, key) { | ||
@@ -47,1 +77,2 @@ var hmac = crypto.createHmac('sha1', key); | ||
module.exports = encodeToken; | ||
{ | ||
"name": "opentok-token", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "Generates tokens for `X-TB-TOKEN-AUTH` header when using OpenTok REST API.", | ||
@@ -15,3 +15,4 @@ "repository": { | ||
"scripts": { | ||
"test": "tap ./test" | ||
"test": "tap ./test", | ||
"docs": "rm -rf docs/; doxx --source . --ignore node_modules,helpers.js,test --title \"OpenTok Token Encoder\"" | ||
}, | ||
@@ -28,4 +29,10 @@ "keywords": [ | ||
"devDependencies": { | ||
"doxx": "^1.2.5", | ||
"tap": "^0.6.0" | ||
}, | ||
"dependencies": { | ||
"lodash": "^3.2.0", | ||
"nonce": "^1.0.3", | ||
"unix-timestamp": "^0.1.2" | ||
} | ||
} |
@@ -23,3 +23,3 @@ # OpenTok Token Encoder | ||
```javascript | ||
var tokenEncoder = require('opentok-token'); | ||
var encodeToken = require('opentok-token'); | ||
@@ -37,4 +37,18 @@ var tokenData = { | ||
var token = tokenEncoder(tokenData, apiKey, apiSecret); | ||
var token = encodeToken(tokenData, apiKey, apiSecret); | ||
``` | ||
**NOTE:** The API key, secret, and session ID above are not real. | ||
### Default values | ||
If you do not specify certain properties of the `tokenData` parameter, defaults will be applied for | ||
you. | ||
| Property | Type | Default | | ||
|---------------|-------------------------------------|-----------------------------| | ||
| `create_time` | unix timestamp in seconds (integer) | now | | ||
| `expire_time` | unix timestamp in seconds (integer) | now + 1 day | | ||
| `role` | string | 'publisher' | | ||
| `nonce` | number | unique random number | | ||
var test = require('tap').test; | ||
var tokenEncoder = require('../index.js'); | ||
var encodeToken = require('..'); | ||
var helpers = require('../helpers'); | ||
// fixtures | ||
// the API Key and Secret are fake | ||
var apiKey = '123456'; | ||
var apiSecret = '1234567890abcdef1234567890abcdef1234567890'; | ||
test('exports a single function', function(t) { | ||
t.type(tokenEncoder, 'function'); | ||
t.type(encodeToken, 'function'); | ||
t.end(); | ||
}); | ||
test('encodes a token', function(t) { | ||
test('encodes a known token', function(t) { | ||
// fixtures | ||
// the API Key and Secret are fake | ||
var apiKey = '123456'; | ||
var apiSecret = '1234567890abcdef1234567890abcdef1234567890'; | ||
var tokenData = { | ||
@@ -23,6 +26,5 @@ // this is a fake session ID made specifically to work with the fake API Key and Secret | ||
}; | ||
var expectedToken = 'T1==cGFydG5lcl9pZD0xMjM0NTYmc2lnPWRmOTRhNjQ1NTlhY2MwNjFkN2EzNzUyYTZmYzY5NDkzZTkzOGMxOTE6c2Vzc2lvbl9pZD0xX01YNHhNak0wTlRaLWZsTmhkQ0JOWVhJZ01UVWdNVFE2TkRJNk1qTWdVRVJVSURJd01UUi1NQzQwT1RBeE16QXlOWDQmY3JlYXRlX3RpbWU9MTQyNDIyMTAxMyZub25jZT0wLjM5NDI2MDk4ODEwNTA4ODUmcm9sZT1tb2RlcmF0b3ImZXhwaXJlX3RpbWU9MTQyNDMwNzQxMyZjb25uZWN0aW9uX2RhdGE9JTdCJTIybmFtZSUyMiUzQSUyMnZhbHVlJTIyJTdE'; | ||
var actualToken = tokenEncoder(tokenData, apiKey, apiSecret); | ||
var actualToken = encodeToken(tokenData, apiKey, apiSecret); | ||
@@ -32,1 +34,66 @@ t.equal(actualToken, expectedToken); | ||
}); | ||
test('provides defaults', function(t) { | ||
// Fixtures | ||
var tokenData = { | ||
// this is a fake session ID made specifically to work with the fake API Key and Secret | ||
session_id: 'SESSIONID' | ||
}; | ||
var token = encodeToken(tokenData, apiKey, apiSecret); | ||
decoded = helpers.decodeToken(token); | ||
t.ok('create_time' in decoded, 'create_time has default'); | ||
t.ok('expire_time' in decoded, 'expire_time has default'); | ||
t.ok('role' in decoded, 'role has default'); | ||
t.ok('nonce' in decoded, 'nonce has default'); | ||
t.test('create_time default is now', function(t) { | ||
var createTime = parseInt(decoded.create_time, 10); | ||
var now = Math.round(Date.now() / 1000); | ||
t.ok(createTime >= (now - 1)); | ||
t.ok(createTime <= (now + 1)); | ||
t.end(); | ||
}); | ||
t.test('expire_time default is in one day', function(t) { | ||
var expireTime = parseInt(decoded.expire_time, 10); | ||
var inOneDay = Math.round(Date.now() / 1000) + (60*60*24); | ||
t.ok(expireTime >= (inOneDay - 1)); | ||
t.ok(expireTime <= (inOneDay + 1)); | ||
t.end(); | ||
}); | ||
t.test('times are whole numbers', function(t) { | ||
t.ok(decoded.create_time.indexOf('.') === -1); | ||
t.ok(decoded.expire_time.indexOf('.') === -1); | ||
t.end(); | ||
}); | ||
t.equal(decoded.role, 'publisher', 'role default is \'publisher\''); | ||
t.test('nonce default is a unique number', function(t) { | ||
var nonce2 = helpers.decodeToken(encodeToken(tokenData, apiKey, apiSecret)).nonce; | ||
t.ok(decoded.nonce !== nonce2); | ||
t.end(); | ||
}); | ||
t.end(); | ||
}); | ||
test('contains a verified signature', function(t) { | ||
var tokenData = { | ||
session_id: 'SESSIONID', | ||
role: 'moderator' | ||
}; | ||
var token = encodeToken(tokenData, apiKey, apiSecret); | ||
t.ok(helpers.verifyTokenSignature(token, apiSecret)); | ||
t.end(); | ||
}); | ||
test('does not verify bad values', function(t) { | ||
var noSessionTokenData = {}; | ||
var token = encodeToken(noSessionTokenData, apiKey, apiSecret); | ||
t.type(token, 'string'); | ||
t.ok(helpers.verifyTokenSignature(token, apiSecret)); | ||
t.end(); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
10047
8
171
53
3
2
+ Addedlodash@^3.2.0
+ Addednonce@^1.0.3
+ Addedunix-timestamp@^0.1.2
+ Addedlodash@3.10.1(transitive)
+ Addednonce@1.0.4(transitive)
+ Addedunix-timestamp@0.1.2(transitive)