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