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.
		
		
		
		
		
			
		
			
				
					184 lines
				
				5.9 KiB
			
		
		
			
		
	
	
					184 lines
				
				5.9 KiB
			| 
											3 years ago
										 | var jwt = require('jsonwebtoken'); | ||
|  | var deprecate = require('deprecate'); | ||
|  | var _ = require('underscore') | ||
|  | require('string.prototype.startswith'); | ||
|  | 
 | ||
|  | var taskRouterUrlBase = 'https://taskrouter.twilio.com'; | ||
|  | var taskRouterVersion = 'v1'; | ||
|  | var eventUrlBase = 'https://event-bridge.twilio.com/v1/wschannels'; | ||
|  | 
 | ||
|  | function TaskRouterCapability(accountSid, authToken, workspaceSid, channelId) { | ||
|  |     this.accountSid = accountSid; | ||
|  |     this.authToken = authToken; | ||
|  |     this.policies = []; | ||
|  | 
 | ||
|  |     this.workspaceSid = workspaceSid; | ||
|  |     this.channelId = channelId; | ||
|  | 
 | ||
|  |     this._baseUrl = taskRouterUrlBase + '/' + taskRouterVersion + '/Workspaces/' + this.workspaceSid; | ||
|  | 
 | ||
|  |     this._validateJWT(); | ||
|  | 
 | ||
|  |     this._setupResource(); | ||
|  | 
 | ||
|  |     var eventsUrl = eventUrlBase + '/' + this.accountSid + '/' + channelId; | ||
|  | 
 | ||
|  |     // add permissions to GET and POST to the event-bridge channel
 | ||
|  |     this.allow(eventsUrl, 'GET'); | ||
|  |     this.allow(eventsUrl, 'POST'); | ||
|  | 
 | ||
|  |     // add permission to fetch the instance resource
 | ||
|  |     this.allow(this._resourceUrl, 'GET'); | ||
|  | } | ||
|  | 
 | ||
|  | TaskRouterCapability.prototype._setupResource = function() { | ||
|  |     if(this.channelId.startsWith('WS')) { | ||
|  |         this._resourceUrl = this._baseUrl; | ||
|  |     }else if(this.channelId.startsWith('WK')) { | ||
|  |         this._resourceUrl = this._baseUrl + '/Workers/' + this.channelId; | ||
|  | 
 | ||
|  |         var activityUrl = this._baseUrl + '/Activities'; | ||
|  |         this.allow(activityUrl, "GET"); | ||
|  | 
 | ||
|  |         var tasksUrl = this._baseUrl + '/Tasks/**'; | ||
|  |         this.allow(tasksUrl, "GET"); | ||
|  | 
 | ||
|  |         var workerReservationsUrl = this._resourceUrl + '/Reservations/**'; | ||
|  |         this.allow(workerReservationsUrl, "GET"); | ||
|  | 
 | ||
|  |     }else if(this.channelId.startsWith('WQ')) { | ||
|  |         this._resourceUrl = this._baseUrl + '/TaskQueues/' + this.channelId; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | TaskRouterCapability.prototype._validateJWT = function() { | ||
|  |     if(!this.accountSid || !this.accountSid.startsWith('AC')) { | ||
|  |         throw "Invalid AccountSid provided: "+this.accountSid; | ||
|  |     } | ||
|  |     if(!this.workspaceSid || !this.workspaceSid.startsWith('WS')) { | ||
|  |         throw "Invalid WorkspaceSid provided: "+this.workspaceSid; | ||
|  |     } | ||
|  |     if(!this.channelId) { | ||
|  |         throw "ChannelId not provided"; | ||
|  |     } | ||
|  |     var prefix = this.channelId.substring(0,2); | ||
|  |     if(prefix != 'WS' && prefix != 'WK' && prefix != 'WQ') { | ||
|  |         throw "Invalid ChannelId provided: "+this.channelId; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | TaskRouterCapability.prototype.allowFetchSubresources = function() { | ||
|  |     this.allow(this._resourceUrl+'/**', 'GET'); | ||
|  | } | ||
|  | 
 | ||
|  | TaskRouterCapability.prototype.allowUpdates = function() { | ||
|  |     this.allow(this._resourceUrl, 'POST'); | ||
|  | } | ||
|  | 
 | ||
|  | TaskRouterCapability.prototype.allowUpdatesSubresources = function() { | ||
|  |     this.allow(this._resourceUrl+'/**', 'POST'); | ||
|  | } | ||
|  | 
 | ||
|  | TaskRouterCapability.prototype.allowDelete = function() { | ||
|  |     this.allow(this._resourceUrl, 'DELETE'); | ||
|  | } | ||
|  | 
 | ||
|  | TaskRouterCapability.prototype.allowDeleteSubresources = function() { | ||
|  |     this.allow(this._resourceUrl+'/**', 'DELETE'); | ||
|  | } | ||
|  | 
 | ||
|  | TaskRouterCapability.prototype.allowDeleteSubresources = function() { | ||
|  |     this.allow(this._resourceUrl+'/**', 'DELETE'); | ||
|  | } | ||
|  | 
 | ||
|  | TaskRouterCapability.prototype.allowWorkerActivityUpdates = function() { | ||
|  |     if(this.channelId.startsWith('WK')) { | ||
|  |         deprecate('allowWorkerActivityUpdates is deprecated. Please use TaskRouterWorkerCapability.allowWorkerActivityUpdates() instead'); | ||
|  |         this.allow(this._resourceUrl, 'POST', {}, {"ActivitySid": {'required': true}}); | ||
|  |     }else { | ||
|  |         throw "Deprecated function not applicable to non Worker"; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | TaskRouterCapability.prototype.allowWorkerFetchAttributes = function() { | ||
|  |     if(this.channelId.startsWith('WK')) { | ||
|  |         deprecate('allowWorkerFetchAttributes is deprecated. Please use TaskRouterWorkerCapability; added automatically in constructor'); | ||
|  |         this.allow(this._resourceUrl, 'GET'); | ||
|  |     }else { | ||
|  |         throw "Deprecated function not applicable to non Worker"; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | TaskRouterCapability.prototype.allowTaskReservationUpdates = function() { | ||
|  |     if(this.channelId.startsWith('WK')) { | ||
|  |         deprecate('allowTaskReservationUpdates is deprecated. Please use TaskRouterWorkerCapability.allowReservationUpdates() instead'); | ||
|  |         this.allow(this._baseUrl + "/Tasks/**", "POST"); | ||
|  |     }else { | ||
|  |         throw "Deprecated function not applicable to non Worker"; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | TaskRouterCapability.prototype.addPolicy = function(url, method, allowed, queryFilter, postFilter) { | ||
|  |     var policy = { | ||
|  |         url: url, | ||
|  |         method: method | ||
|  |     }; | ||
|  | 
 | ||
|  |     if (queryFilter) { | ||
|  |         policy.query_filter = queryFilter; | ||
|  |     } else { | ||
|  |         policy.query_filter = {}; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (postFilter) { | ||
|  |         policy.post_filter = postFilter; | ||
|  |     } else { | ||
|  |         policy.post_filter = {}; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (typeof allowed !== 'undefined') { | ||
|  |         policy.allow = allowed; | ||
|  |     } else { | ||
|  |         policy.allow = true; | ||
|  |     } | ||
|  |     this.policies.push(policy); | ||
|  | } | ||
|  | 
 | ||
|  | TaskRouterCapability.prototype.allow = function(url, method, queryFilter, postFilter) { | ||
|  |     this.addPolicy(url, method, true, queryFilter, postFilter); | ||
|  | } | ||
|  | 
 | ||
|  | TaskRouterCapability.prototype.deny = function(url, method, queryFilter, postFilter) { | ||
|  |     this.addPolicy(url, method, false, queryFilter, postFilter); | ||
|  | } | ||
|  | 
 | ||
|  | TaskRouterCapability.prototype.generate = function(ttl) { | ||
|  |     var taskRouterAttributes = { | ||
|  |         'account_sid': this.accountSid, | ||
|  |         'channel': this.channelId, | ||
|  |         'workspace_sid': this.workspaceSid | ||
|  |     } | ||
|  | 
 | ||
|  |     if(this.channelId.startsWith('WK')) { | ||
|  |         taskRouterAttributes.worker_sid = this.channelId; | ||
|  |     }else if(this.channelId.startsWith('WQ')) { | ||
|  |         taskRouterAttributes.taskqueue_sid = this.channelId; | ||
|  |     } | ||
|  | 
 | ||
|  |     return this._generate(ttl, taskRouterAttributes); | ||
|  | } | ||
|  | 
 | ||
|  | TaskRouterCapability.prototype._generate = function(ttl, extraAttributes) { | ||
|  |     var payload = { | ||
|  |         iss: this.accountSid, | ||
|  |         exp: (Math.floor(new Date() / 1000) + (ttl || 3600)), | ||
|  |         version: taskRouterVersion, | ||
|  |         friendly_name: this.channelId, | ||
|  |         policies: this.policies, | ||
|  |     }; | ||
|  |     _.extend(payload, extraAttributes); | ||
|  |     return jwt.sign(payload, this.authToken); | ||
|  | } | ||
|  | 
 | ||
|  | module.exports = TaskRouterCapability; |