module.exports = function(RED) { var https = require('https'); var http = require('http'); var url = require('url'); var OPERATIONS = { // Status 'status:get': { method:'GET', path:'/status.php' }, // Capabilities 'capabilities:get': { method:'GET', path:'/ocs/v2.php/cloud/capabilities' }, // App password 'appPassword:get': { method:'GET', path:'/ocs/v2.php/core/getapppassword' }, 'appPassword:oneTime': { method:'GET', path:'/ocs/v2.php/core/getapppassword-onetime' }, 'appPassword:delete': { method:'DELETE', path:'/ocs/v2.php/core/apppassword' }, 'appPassword:rotate': { method:'POST', path:'/ocs/v2.php/core/apppassword/rotate' }, 'appPassword:confirm': { method:'PUT', path:'/ocs/v2.php/core/apppassword/confirm', body:['password'] }, // Autocomplete 'autocomplete:get': { method:'GET', path:'/ocs/v2.php/core/autocomplete/get', query:['search','itemType','itemId','sorter','limit'] }, // Navigation 'nav:apps': { method:'GET', path:'/ocs/v2.php/core/navigation/apps', query:['absolute'] }, 'nav:settings': { method:'GET', path:'/ocs/v2.php/core/navigation/settings', query:['absolute'] }, // Profile 'profile:get': { method:'GET', path:'/ocs/v2.php/profile/{userId}' }, 'profile:setVisibility': { method:'PUT', path:'/ocs/v2.php/profile/{userId}', body:['paramId','visibility'] }, // Hover card 'hovercard:get': { method:'GET', path:'/ocs/v2.php/hovercard/v1/{userId}' }, // Collaboration resources 'collab:get': { method:'GET', path:'/ocs/v2.php/collaboration/resources/collections/{collectionId}' }, 'collab:addResource': { method:'POST', path:'/ocs/v2.php/collaboration/resources/collections/{collectionId}', body:['resourceType','resourceId'] }, 'collab:removeResource': { method:'DELETE', path:'/ocs/v2.php/collaboration/resources/collections/{collectionId}', query:['resourceType','resourceId'] }, 'collab:rename': { method:'PUT', path:'/ocs/v2.php/collaboration/resources/collections/{collectionId}', body:['collectionName'] }, 'collab:search': { method:'GET', path:'/ocs/v2.php/collaboration/resources/collections/search/{filter}' }, 'collab:byResource': { method:'GET', path:'/ocs/v2.php/collaboration/resources/{resourceType}/{resourceId}' }, 'collab:create': { method:'POST', path:'/ocs/v2.php/collaboration/resources/{baseResourceType}/{baseResourceId}', body:['name'] }, // References 'ref:extract': { method:'POST', path:'/ocs/v2.php/references/extract', body:['text','resolve','limit'] }, 'ref:resolve': { method:'GET', path:'/ocs/v2.php/references/resolve', query:['reference'] }, 'ref:resolveMany': { method:'POST', path:'/ocs/v2.php/references/resolve', body:['references','limit'] }, 'ref:providers': { method:'GET', path:'/ocs/v2.php/references/providers' }, 'ref:touchProvider': { method:'PUT', path:'/ocs/v2.php/references/provider/{providerId}', body:['timestamp'] }, // Preview 'preview:byPath': { method:'GET', path:'/index.php/core/preview.png', query:['file','x','y','a','forceIcon','mode'] }, 'preview:byFileId': { method:'GET', path:'/index.php/core/preview', query:['fileId','x','y','a','forceIcon','mode'] }, // Avatars 'avatar:user': { method:'GET', path:'/index.php/avatar/{userId}/{size}' }, 'avatar:userDark': { method:'GET', path:'/index.php/avatar/{userId}/{size}/dark' }, 'avatar:guest': { method:'GET', path:'/index.php/avatar/guest/{guestName}/{size}' }, // CSRF 'csrf:get': { method:'GET', path:'/index.php/csrftoken' }, // Login flow 'login:init': { method:'POST', path:'/index.php/login/v2' }, 'login:poll': { method:'POST', path:'/index.php/login/v2/poll', body:['token'] }, 'login:confirm': { method:'POST', path:'/index.php/login/confirm', body:['password'] }, // Wipe 'wipe:check': { method:'POST', path:'/index.php/core/wipe/check', body:['token'] }, 'wipe:done': { method:'POST', path:'/index.php/core/wipe/success', body:['token'] }, // OCM 'ocm:discovery': { method:'GET', path:'/index.php/ocm-provider' }, // Unified search 'search:providers': { method:'GET', path:'/ocs/v2.php/search/providers', query:['from'] }, 'search:execute': { method:'GET', path:'/ocs/v2.php/search/providers/{providerId}/search', query:['term','sortOrder','limit','cursor','from'] }, // Task processing 'task:types': { method:'GET', path:'/ocs/v2.php/taskprocessing/tasktypes' }, 'task:schedule': { method:'POST', path:'/ocs/v2.php/taskprocessing/schedule', body:['input','type','appId','customId'] }, 'task:get': { method:'GET', path:'/ocs/v2.php/taskprocessing/task/{id}' }, 'task:delete': { method:'DELETE', path:'/ocs/v2.php/taskprocessing/task/{id}' }, 'task:list': { method:'GET', path:'/ocs/v2.php/taskprocessing/tasks', query:['taskType','customId'] }, 'task:listByApp': { method:'GET', path:'/ocs/v2.php/taskprocessing/tasks/app/{appId}', query:['customId'] }, 'task:cancel': { method:'POST', path:'/ocs/v2.php/taskprocessing/tasks/{taskId}/cancel' }, // Text processing 'text:types': { method:'GET', path:'/ocs/v2.php/textprocessing/tasktypes' }, 'text:schedule': { method:'POST', path:'/ocs/v2.php/textprocessing/schedule', body:['input','type','appId','identifier'] }, 'text:get': { method:'GET', path:'/ocs/v2.php/textprocessing/task/{id}' }, 'text:delete': { method:'DELETE', path:'/ocs/v2.php/textprocessing/task/{id}' }, 'text:listByApp': { method:'GET', path:'/ocs/v2.php/textprocessing/tasks/app/{appId}', query:['identifier'] }, // Translation 'translate:languages': { method:'GET', path:'/ocs/v2.php/translation/languages' }, 'translate:text': { method:'POST', path:'/ocs/v2.php/translation/translate', body:['text','fromLanguage','toLanguage'] }, // Text to image 't2i:available': { method:'GET', path:'/ocs/v2.php/text2image/is_available' }, 't2i:schedule': { method:'POST', path:'/ocs/v2.php/text2image/schedule', body:['input','appId','identifier','numberOfImages'] }, 't2i:get': { method:'GET', path:'/ocs/v2.php/text2image/task/{id}' }, 't2i:delete': { method:'DELETE', path:'/ocs/v2.php/text2image/task/{id}' }, 't2i:image': { method:'GET', path:'/ocs/v2.php/text2image/task/{id}/image/{index}' }, 't2i:listByApp': { method:'GET', path:'/ocs/v2.php/text2image/tasks/app/{appId}', query:['identifier'] }, // Teams 'teams:resources': { method:'GET', path:'/ocs/v2.php/teams/{teamId}/resources' }, 'teams:ofResource': { method:'GET', path:'/ocs/v2.php/teams/resources/{providerId}/{resourceId}' } }; function CoreNode(config) { RED.nodes.createNode(this, config); var node = this; this.configNode = RED.nodes.getNode(config.nextcloud); this.operation = config.operation || 'status:get'; this.userId = config.userId; this.collectionId = config.collectionId; this.resourceType = config.resourceType; this.resourceId = config.resourceId; this.providerId = config.providerId; this.appId = config.appId; this.taskId = config.taskId; this.teamId = config.teamId; this.guestName = config.guestName; this.size = config.size; this.filter = config.filter; this.baseResourceType = config.baseResourceType; this.baseResourceId = config.baseResourceId; if (!this.configNode) { node.error("No NC config node"); return; } node.on('input', function(msg) { var op = OPERATIONS[msg.operation || node.operation]; if (!op) { node.error("Unknown: "+(msg.operation||node.operation), msg); return; } var baseUrl = (node.configNode.baseUrl||'').replace(/\/+$/,''); var uname = node.configNode.credentials.username; var pw = node.configNode.credentials.password; var path = op.path .replace(/\{userId\}/g, msg.userId||node.userId||'') .replace(/\{collectionId\}/g, msg.collectionId||node.collectionId||'') .replace(/\{resourceType\}/g, msg.resourceType||node.resourceType||'') .replace(/\{resourceId\}/g, msg.resourceId||node.resourceId||'') .replace(/\{providerId\}/g, msg.providerId||node.providerId||'') .replace(/\{appId\}/g, msg.appId||node.appId||'') .replace(/\{id\}/g, msg.taskId||node.taskId||msg.id||'') .replace(/\{taskId\}/g, msg.taskId||node.taskId||'') .replace(/\{teamId\}/g, msg.teamId||node.teamId||'') .replace(/\{guestName\}/g, msg.guestName||node.guestName||'') .replace(/\{size\}/g, msg.size||node.size||'64') .replace(/\{filter\}/g, msg.filter||node.filter||'') .replace(/\{baseResourceType\}/g, msg.baseResourceType||node.baseResourceType||'') .replace(/\{baseResourceId\}/g, msg.baseResourceId||node.baseResourceId||'') .replace(/\{index\}/g, msg.index||'0'); var qp = []; if (op.query) op.query.forEach(function(q) { var v = msg[q]!==undefined ? msg[q] : getF(node,q); if (v!==undefined&&v!=='') qp.push(encodeURIComponent(q)+'='+encodeURIComponent(v)); }); var fu = baseUrl+path+(qp.length?'?'+qp.join('&'):''); var pu = url.parse(fu); var h = {'Accept':'application/json', 'Authorization':'Basic '+Buffer.from(uname+':'+pw).toString('base64')}; if (path.indexOf('/ocs/')===0) h['OCS-APIRequest']='true'; var bo={}; if (op.body) op.body.forEach(function(b){ var v=msg[b]!==undefined?msg[b]:getF(node,b); if(v!==undefined&&v!=='') bo[b]=v; }); var bs=null; if (Object.keys(bo).length>0) {h['Content-Type']='application/json'; bs=JSON.stringify(bo);} var o = {hostname:pu.hostname,port:pu.port||(pu.protocol==='https:'?443:80), path:pu.path,method:op.method,headers:h,rejectUnauthorized:false}; node.log(op.method+' '+fu); var t = pu.protocol==='https:'?https:http; var r = t.request(o,function(res){ var b='';res.on('data',function(c){b+=c;}); res.on('end',function(){msg.statusCode=res.statusCode;msg.operation=msg.operation||node.operation; try{msg.payload=JSON.parse(b);}catch(e){msg.payload=b;}node.send(msg);}); }); r.on('error',function(e){msg.error=e.message;node.error(op.method+' '+fu+' - '+e.message,msg);}); if(bs) r.write(bs); r.end(); }); } function getF(node,n){var m={'password':node.bodyPassword,'text':node.bodyText,'search':node.bodySearch};return m[n];} RED.nodes.registerType("core", CoreNode); };