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; |