Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change to jwt tokens #335

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions lib/generateJwt.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
var jwt = require('jsonwebtoken');

module.exports = function (config) {
module.exports = function (config, additionalClaims) {
var currentTime = Math.floor(new Date() / 1000);
var token = jwt.sign({
const initialClaims = {
iss: config.apiKey,
ist: 'project',
iat: currentTime,
exp: currentTime + config.auth.expire
}, config.apiSecret);
exp: additionalClaims?.expire_time || currentTime + config.auth.expire
};

const claims = {...initialClaims, ...additionalClaims};

var token = jwt.sign(claims, config.apiSecret);

return token;
};
13 changes: 6 additions & 7 deletions lib/opentok.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/*
'use strict';

/**
* OpenTok server-side SDK
*/

// Dependencies
var net = require('net');
var _ = require('lodash');
var encodeToken = require('opentok-token');
var Client = require('./client');
var Session = require('./session');
var Stream = require('./stream');
Expand Down Expand Up @@ -488,7 +489,6 @@ OpenTok = function (apiKey, apiSecret, env) {
);
};


/**
* Starts live captions for an OpenTok Session
* <p>
Expand Down Expand Up @@ -549,7 +549,6 @@ OpenTok = function (apiKey, apiSecret, env) {

this.startCaptions = captions.startCaptions.bind(null, apiConfig);


/**
* Stops live captions for an OpenTok Session
*
Expand Down Expand Up @@ -581,7 +580,6 @@ OpenTok = function (apiKey, apiSecret, env) {

this.stopCaptions = captions.stopCaptions.bind(null, apiConfig);


/**
* Retrieves a List of {@link Render} objects, representing any renders in the starting,
* started, stopped or failed state, for your API key.
Expand Down Expand Up @@ -2118,7 +2116,7 @@ OpenTok.prototype.createSession = function (opts, callback) {
*
* </ul>
*
* @return The token string.
* @return {String} The JWT Token that works for the client side
*/

OpenTok.prototype.generateToken = function (sessionId, opts) {
Expand Down Expand Up @@ -2200,8 +2198,9 @@ OpenTok.prototype.generateToken = function (sessionId, opts) {
+ 'concatenated length of less than 1024');
}

return encodeToken(tokenData, this.apiKey, this.apiSecret);
tokenData.scope = 'session.connect';

return generateJwt(this.client.c, tokenData);
};

/*
Expand Down
26 changes: 1 addition & 25 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@
"dependencies": {
"jsonwebtoken": "9.0.2",
"lodash": "4.17.21",
"node-fetch": "2.7.0",
"opentok-token": "1.1.1"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 less is more 😄

"node-fetch": "2.7.0"
},
"devDependencies": {
"chai": "4.3.10",
Expand Down
2 changes: 2 additions & 0 deletions test/helpers.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use strict';

// Test Helpers
var qs = require('querystring');
var crypto = require('crypto');
Expand Down
44 changes: 15 additions & 29 deletions test/opentok-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -907,11 +907,11 @@ describe('#generateToken', function () {
var token = this.opentok.generateToken(this.sessionId);
var decoded;
expect(token).to.be.a('string');
expect(helpers.verifyTokenSignature(token, apiSecret)).to.be.true;
decoded = helpers.decodeToken(token);
expect(decoded.partner_id).to.equal(apiKey);
decoded = jwt.verify(token, apiSecret);
expect(decoded.session_id).to.equal(this.sessionId);
expect(decoded.create_time).to.exist;
expect(decoded.nonce).to.exist;
expect(decoded.role).to.equal('publisher');
});

it('assigns a role in the token', function () {
Expand All @@ -920,18 +920,15 @@ describe('#generateToken', function () {
var decoded;
var subscriberToken;
expect(defaultRoleToken).to.be.a('string');
expect(helpers.verifyTokenSignature(defaultRoleToken, apiSecret)).to.be
.true;
decoded = helpers.decodeToken(defaultRoleToken);
decoded = jwt.verify(defaultRoleToken, apiSecret);
expect(decoded.role).to.equal('publisher');

// expects one with a valid role defined to set it
subscriberToken = this.opentok.generateToken(this.sessionId, {
role: 'subscriber'
});
expect(subscriberToken).to.be.a('string');
expect(helpers.verifyTokenSignature(subscriberToken, apiSecret)).to.be.true;
decoded = helpers.decodeToken(subscriberToken);
decoded = jwt.verify(subscriberToken, apiSecret);
expect(decoded.role).to.equal('subscriber');

// expects one with an invalid role to complain
Expand All @@ -953,24 +950,19 @@ describe('#generateToken', function () {
var inOneHour;
var oneHourAgo;

var fractionalExpireTime;
var roundedToken;

expect(defaultExpireToken).to.be.a('string');
expect(helpers.verifyTokenSignature(defaultExpireToken, apiSecret)).to.be
.true;
decoded = helpers.decodeToken(defaultExpireToken);
decoded = jwt.verify(defaultExpireToken, apiSecret);
expireTime = parseInt(decoded.expire_time, 10);
expect(expireTime).to.be.closeTo(inOneDay, delta);

// expects a token with an expiration time to have it
inOneHour = now + (60 * 60);
oneHourToken = this.opentok.generateToken(this.sessionId, {
expireTime: inOneHour
});
expect(oneHourToken).to.be.a('string');
expect(helpers.verifyTokenSignature(oneHourToken, apiSecret)).to.be.true;
decoded = helpers.decodeToken(oneHourToken);
decoded = jwt.verify(oneHourToken, apiSecret);
expireTime = parseInt(decoded.expire_time, 10);
expect(expireTime).to.be.closeTo(inOneHour, delta);

Expand All @@ -985,13 +977,12 @@ describe('#generateToken', function () {
}).to.throw(Error);

// rounds down fractional expiration time
fractionalExpireTime = now + 60.5;
const fractionalExpireTime = now + 60.5;
roundedToken = this.opentok.generateToken(this.sessionId, {
expireTime: fractionalExpireTime
});
expect(helpers.verifyTokenSignature(roundedToken, apiSecret)).to.be.true;
decoded = helpers.decodeToken(roundedToken);
expect(decoded.expire_time).to.equal(Math.round(fractionalExpireTime).toString());
decoded = jwt.verify(roundedToken, apiSecret);
expect(decoded.exp).to.equal(Math.round(fractionalExpireTime));
});

it('sets initial layout class list in the token', function () {
Expand All @@ -1000,19 +991,15 @@ describe('#generateToken', function () {
var layoutBearingToken = this.opentok.generateToken(this.sessionId, {
initialLayoutClassList: layoutClassList
});
var decoded = helpers.decodeToken(layoutBearingToken);
var decoded = jwt.verify(layoutBearingToken, apiSecret);
var singleLayoutBearingToken = this.opentok.generateToken(this.sessionId, {
initialLayoutClassList: singleLayoutClass
});

expect(layoutBearingToken).to.be.a('string');
expect(helpers.verifyTokenSignature(layoutBearingToken, apiSecret)).to.be
.true;
expect(decoded.initial_layout_class_list).to.equal(layoutClassList.join(' '));
expect(singleLayoutBearingToken).to.be.a('string');
expect(helpers.verifyTokenSignature(singleLayoutBearingToken, apiSecret)).to
.be.true;
decoded = helpers.decodeToken(singleLayoutBearingToken);
decoded = jwt.verify(singleLayoutBearingToken, apiSecret);
expect(decoded.initial_layout_class_list).to.equal(singleLayoutClass);

// NOTE: ignores invalid options instead of throwing an error, except if its too long
Expand All @@ -1032,9 +1019,7 @@ describe('#generateToken', function () {
data: sampleData
});
expect(dataBearingToken).to.be.a('string');
expect(helpers.verifyTokenSignature(dataBearingToken, apiSecret)).to.be
.true;
decoded = helpers.decodeToken(dataBearingToken);
decoded = jwt.verify(dataBearingToken, apiSecret);
expect(decoded.connection_data).to.equal(sampleData);

// expects a token with invalid connection data to complain
Expand Down Expand Up @@ -1066,8 +1051,9 @@ describe('#generateToken', function () {
this.opentok.generateToken(this.sessionId)
];
var nonces = _.map(tokens, function (token) {
return helpers.decodeToken(token).nonce;
return jwt.verify(token, apiSecret).nonce;
});

expect(_.uniq(nonces)).to.have.length(nonces.length);
});

Expand Down
Loading