You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					202 lines
				
				5.8 KiB
			
		
		
			
		
	
	
					202 lines
				
				5.8 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								var _ = require('underscore');
							 | 
						||
| 
								 | 
							
								var jwt = require('jsonwebtoken');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @constructor
							 | 
						||
| 
								 | 
							
								 * @param {object} options - ...
							 | 
						||
| 
								 | 
							
								 * @param {string} options.serviceSid - The service unique ID
							 | 
						||
| 
								 | 
							
								 * @param {string} options.endpointId - The endpoint ID
							 | 
						||
| 
								 | 
							
								 * @param {string} options.deploymentRoleSid - SID of the deployment role to be
							 | 
						||
| 
								 | 
							
								 *                 assigned to the user
							 | 
						||
| 
								 | 
							
								 * @param {string} options.pushCredentialSid - The Push Credentials SID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function IpMessagingGrant(options) {
							 | 
						||
| 
								 | 
							
								  options = options || {};
							 | 
						||
| 
								 | 
							
								  this.serviceSid = options.serviceSid;
							 | 
						||
| 
								 | 
							
								  this.endpointId = options.endpointId;
							 | 
						||
| 
								 | 
							
								  this.deploymentRoleSid = options.deploymentRoleSid;
							 | 
						||
| 
								 | 
							
								  this.pushCredentialSid = options.pushCredentialSid;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								_.extend(IpMessagingGrant.prototype, {
							 | 
						||
| 
								 | 
							
								  key: 'ip_messaging',
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  toPayload: function() {
							 | 
						||
| 
								 | 
							
								    var grant = {};
							 | 
						||
| 
								 | 
							
								    if (this.serviceSid) { grant.service_sid = this.serviceSid; }
							 | 
						||
| 
								 | 
							
								    if (this.endpointId) { grant.endpoint_id = this.endpointId; }
							 | 
						||
| 
								 | 
							
								    if (this.deploymentRoleSid) {
							 | 
						||
| 
								 | 
							
								      grant.deployment_role_sid = this.deploymentRoleSid;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (this.pushCredentialSid) {
							 | 
						||
| 
								 | 
							
								      grant.push_credential_sid = this.pushCredentialSid;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return grant;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @constructor
							 | 
						||
| 
								 | 
							
								 * @param {object} options - ...
							 | 
						||
| 
								 | 
							
								 * @param {string} options.configurationProfileSid - The configuration
							 | 
						||
| 
								 | 
							
								 *                 profile unique ID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function ConversationsGrant(options) {
							 | 
						||
| 
								 | 
							
								  options = options || {};
							 | 
						||
| 
								 | 
							
								  this.configurationProfileSid = options.configurationProfileSid;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								_.extend(ConversationsGrant.prototype, {
							 | 
						||
| 
								 | 
							
								  key: 'rtc',
							 | 
						||
| 
								 | 
							
								  toPayload: function() {
							 | 
						||
| 
								 | 
							
								    var grant = {};
							 | 
						||
| 
								 | 
							
								    if (this.configurationProfileSid) {
							 | 
						||
| 
								 | 
							
								      grant.configuration_profile_sid = this.configurationProfileSid;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return grant;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @constructor
							 | 
						||
| 
								 | 
							
								 * @param {object} options - ...
							 | 
						||
| 
								 | 
							
								 * @param {string} options.configurationProfileSid - The configuration
							 | 
						||
| 
								 | 
							
								 *                 profile unique ID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function VideoGrant(options) {
							 | 
						||
| 
								 | 
							
								  options = options || {};
							 | 
						||
| 
								 | 
							
								  this.configurationProfileSid = options.configurationProfileSid;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								_.extend(VideoGrant.prototype, {
							 | 
						||
| 
								 | 
							
								  key: 'video',
							 | 
						||
| 
								 | 
							
								  toPayload: function() {
							 | 
						||
| 
								 | 
							
								    var grant = {};
							 | 
						||
| 
								 | 
							
								    if (this.configurationProfileSid) {
							 | 
						||
| 
								 | 
							
								      grant.configuration_profile_sid = this.configurationProfileSid;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return grant;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @constructor
							 | 
						||
| 
								 | 
							
								 * @param {object} options - ...
							 | 
						||
| 
								 | 
							
								 * @param {string} options.outgoingApplicationSid - application sid to call when placing outgoing call
							 | 
						||
| 
								 | 
							
								 * @param {object} options.outgoingApplicationParams - request params to pass to the application
							 | 
						||
| 
								 | 
							
								 * @param {string} options.pushCredentialSid - Push Credential Sid to use when registering to receive incoming call notifications
							 | 
						||
| 
								 | 
							
								 * @param {string} options.endpointId - Specify an endpoint identifier for this device, which will allow the developer
							 | 
						||
| 
								 | 
							
								 *                 to direct calls to a specific endpoint when multiple devices are associated with a single identity
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function VoiceGrant(options) {
							 | 
						||
| 
								 | 
							
								  options = options || {};
							 | 
						||
| 
								 | 
							
								  this.outgoingApplicationSid = options.outgoingApplicationSid;
							 | 
						||
| 
								 | 
							
								  this.outgoingApplicationParams = options.outgoingApplicationParams;
							 | 
						||
| 
								 | 
							
								  this.pushCredentialSid = options.pushCredentialSid;
							 | 
						||
| 
								 | 
							
								  this.endpointId = options.endpointId;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								_.extend(VoiceGrant.prototype, {
							 | 
						||
| 
								 | 
							
								  key: 'voice',
							 | 
						||
| 
								 | 
							
								  toPayload: function() {
							 | 
						||
| 
								 | 
							
								    var grant = {};
							 | 
						||
| 
								 | 
							
								    if (this.outgoingApplicationSid) {
							 | 
						||
| 
								 | 
							
								      grant.outgoing = {};
							 | 
						||
| 
								 | 
							
								      grant.outgoing.application_sid = this.outgoingApplicationSid;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (this.outgoingApplicationParams) {
							 | 
						||
| 
								 | 
							
								        grant.outgoing.params = this.outgoingApplicationParams;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (this.pushCredentialSid) {
							 | 
						||
| 
								 | 
							
								      grant.push_credential_sid = this.pushCredentialSid;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (this.endpointId) {
							 | 
						||
| 
								 | 
							
								      grant.endpoint_id = this.endpointId;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return grant;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @constructor
							 | 
						||
| 
								 | 
							
								 * @param {string} accountSid - The account's unique ID to which access is scoped
							 | 
						||
| 
								 | 
							
								 * @param {string} keySid - The signing key's unique ID
							 | 
						||
| 
								 | 
							
								 * @param {string} secret - The secret to sign the token with
							 | 
						||
| 
								 | 
							
								 * @param {object} opts - ...
							 | 
						||
| 
								 | 
							
								 * @param {number} [opts.ttl=3600] - Time to live in seconds
							 | 
						||
| 
								 | 
							
								 * @param {string} [opts.identity] - The identity of the first person
							 | 
						||
| 
								 | 
							
								 * @param {number} [opts.nbf] - Time from epoch in seconds for not before value
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function AccessToken(accountSid, keySid, secret, opts) {
							 | 
						||
| 
								 | 
							
								  if (!accountSid) { throw new Error('accountSid is required'); }
							 | 
						||
| 
								 | 
							
								  if (!keySid) { throw new Error('keySid is required'); }
							 | 
						||
| 
								 | 
							
								  if (!secret) { throw new Error('secret is required'); }
							 | 
						||
| 
								 | 
							
								  opts = opts || {};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this.accountSid = accountSid;
							 | 
						||
| 
								 | 
							
								  this.keySid = keySid;
							 | 
						||
| 
								 | 
							
								  this.secret = secret;
							 | 
						||
| 
								 | 
							
								  this.ttl = opts.ttl || 3600;
							 | 
						||
| 
								 | 
							
								  this.identity = opts.identity;
							 | 
						||
| 
								 | 
							
								  this.nbf = opts.nbf;
							 | 
						||
| 
								 | 
							
								  this.grants = [];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Class level properties
							 | 
						||
| 
								 | 
							
								AccessToken.IpMessagingGrant = IpMessagingGrant;
							 | 
						||
| 
								 | 
							
								AccessToken.ConversationsGrant = ConversationsGrant;
							 | 
						||
| 
								 | 
							
								AccessToken.VoiceGrant = VoiceGrant;
							 | 
						||
| 
								 | 
							
								AccessToken.VideoGrant = VideoGrant;
							 | 
						||
| 
								 | 
							
								AccessToken.DEFAULT_ALGORITHM = 'HS256';
							 | 
						||
| 
								 | 
							
								AccessToken.ALGORITHMS = [
							 | 
						||
| 
								 | 
							
								  'HS256',
							 | 
						||
| 
								 | 
							
								  'HS384',
							 | 
						||
| 
								 | 
							
								  'HS512'
							 | 
						||
| 
								 | 
							
								];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								_.extend(AccessToken.prototype, {
							 | 
						||
| 
								 | 
							
								  addGrant: function(grant) {
							 | 
						||
| 
								 | 
							
								    this.grants.push(grant);
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  toJwt: function(algorithm) {
							 | 
						||
| 
								 | 
							
								    algorithm = algorithm || AccessToken.DEFAULT_ALGORITHM;
							 | 
						||
| 
								 | 
							
								    if (!_.contains(AccessToken.ALGORITHMS, algorithm)) {
							 | 
						||
| 
								 | 
							
								      throw new Error('Algorithm not supported. Allowed values are ' +
							 | 
						||
| 
								 | 
							
								        AccessToken.ALGORITHMS.join(', '));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var grants = {};
							 | 
						||
| 
								 | 
							
								    if (_.isString(this.identity)) { grants.identity = this.identity; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    _.each(this.grants, function(grant) {
							 | 
						||
| 
								 | 
							
								      grants[grant.key] = grant.toPayload();
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var now = Math.floor(Date.now() / 1000);
							 | 
						||
| 
								 | 
							
								    var payload = {
							 | 
						||
| 
								 | 
							
								      jti: this.keySid + '-' + now,
							 | 
						||
| 
								 | 
							
								      grants: grants
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    if (_.isNumber(this.nbf)) { payload.nbf = this.nbf; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return jwt.sign(payload, this.secret, {
							 | 
						||
| 
								 | 
							
								      headers: {
							 | 
						||
| 
								 | 
							
								        cty: 'twilio-fpa;v=1',
							 | 
						||
| 
								 | 
							
								        typ: 'JWT'
							 | 
						||
| 
								 | 
							
								      },
							 | 
						||
| 
								 | 
							
								      algorithm: algorithm,
							 | 
						||
| 
								 | 
							
								      issuer: this.keySid,
							 | 
						||
| 
								 | 
							
								      subject: this.accountSid,
							 | 
						||
| 
								 | 
							
								      expiresIn: this.ttl
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = AccessToken;
							 |