Files

85 lines
4.5 KiB
JavaScript

module.exports = function(RED) {
var https = require('https');
var http = require('http');
var url = require('url');
var OPERATIONS = {
'direct:url': { method:'POST', path:'/ocs/v2.php/apps/dav/api/v1/direct', body:['fileId','expirationTime'] },
'events:upcoming': { method:'GET', path:'/ocs/v2.php/apps/dav/api/v1/events/upcoming', query:['location'] },
'ooo:current': { method:'GET', path:'/ocs/v2.php/apps/dav/api/v1/outOfOffice/{userId}/now' },
'ooo:get': { method:'GET', path:'/ocs/v2.php/apps/dav/api/v1/outOfOffice/{userId}' },
'ooo:set': { method:'POST', path:'/ocs/v2.php/apps/dav/api/v1/outOfOffice/{userId}', body:['firstDay','lastDay','status','message','replacementUserId'] },
'ooo:clear': { method:'DELETE',path:'/ocs/v2.php/apps/dav/api/v1/outOfOffice/{userId}' }
};
function DavNode(config) {
RED.nodes.createNode(this, config);
var node = this;
this.configNode = RED.nodes.getNode(config.nextcloud);
this.operation = config.operation || 'direct:url';
this.userId = config.userId;
this.bodyFileId = config.bodyFileId; this.bodyExpirationTime = config.bodyExpirationTime;
this.bodyFirstDay = config.bodyFirstDay; this.bodyLastDay = config.bodyLastDay;
this.bodyStatus = config.bodyStatus; this.bodyMessage = config.bodyMessage;
this.bodyReplacementUserId = config.bodyReplacementUserId;
this.bodyLocation = config.bodyLocation;
if (!this.configNode) { node.error("No Nextcloud configuration node selected"); return; }
node.on('input', function(msg) {
var op = OPERATIONS[msg.operation || node.operation];
if (!op) { node.error("Unknown operation: " + (msg.operation || node.operation), msg); return; }
var baseUrl = (node.configNode.baseUrl || '').replace(/\/+$/, '');
var username = node.configNode.credentials.username;
var password = node.configNode.credentials.password;
var path = op.path.replace('{userId}', msg.userId || node.userId || '');
var queryParts = [];
if (op.query) {
op.query.forEach(function(q) {
var v = msg[q] !== undefined ? msg[q] : getField(node, q);
if (v !== undefined && v !== '') queryParts.push(encodeURIComponent(q) + '=' + encodeURIComponent(v));
});
}
var fullUrl = baseUrl + path + (queryParts.length ? '?' + queryParts.join('&') : '');
var parsedUrl = url.parse(fullUrl);
var headers = { 'OCS-APIRequest':'true','Accept':'application/json',
'Authorization':'Basic '+Buffer.from(username+':'+password).toString('base64') };
var bodyObj = {};
if (op.body) {
op.body.forEach(function(b) {
var v = msg[b] !== undefined ? msg[b] : getField(node, b);
if (v !== undefined && v !== '') bodyObj[b] = v;
});
}
var bodyStr = null;
if (Object.keys(bodyObj).length > 0) { headers['Content-Type']='application/json'; bodyStr=JSON.stringify(bodyObj); }
var opts = { hostname:parsedUrl.hostname, port:parsedUrl.port||(parsedUrl.protocol==='https:'?443:80),
path:parsedUrl.path, method:op.method, headers:headers, rejectUnauthorized:false };
node.log(op.method+' '+fullUrl);
var transport = parsedUrl.protocol==='https:'?https:http;
var req = transport.request(opts, function(res) {
var body=''; res.on('data',function(c){body+=c;});
res.on('end',function(){ msg.statusCode=res.statusCode; msg.operation=msg.operation||node.operation;
try{msg.payload=JSON.parse(body);}catch(e){msg.payload=body;} node.send(msg); });
});
req.on('error',function(err){msg.error=err.message;node.error(op.method+' '+fullUrl+' — '+err.message,msg);});
if(bodyStr) req.write(bodyStr);
req.end();
});
}
function getField(node,name) {
var m={ 'fileId':node.bodyFileId,'expirationTime':node.bodyExpirationTime,'firstDay':node.bodyFirstDay,
'lastDay':node.bodyLastDay,'status':node.bodyStatus,'message':node.bodyMessage,
'replacementUserId':node.bodyReplacementUserId,'location':node.bodyLocation };
return m[name];
}
RED.nodes.registerType("dav", DavNode);
};