Files
nextcloud-nodered-ocs-api/nodes/nextcloud-ocs/tables.js
T

162 lines
11 KiB
JavaScript
Raw Normal View History

module.exports = function(RED) {
var https = require('https');
var http = require('http');
var url = require('url');
var OPERATIONS = {
// Tables (api v2 OCS)
'table:list': { method:'GET', path:'/ocs/v2.php/apps/tables/api/2/tables' },
'table:get': { method:'GET', path:'/ocs/v2.php/apps/tables/api/2/tables/{id}' },
'table:create': { method:'POST', path:'/ocs/v2.php/apps/tables/api/2/tables', body:['title','emoji','description','template'] },
'table:update': { method:'PUT', path:'/ocs/v2.php/apps/tables/api/2/tables/{id}', body:['title','emoji','description','archived'] },
'table:delete': { method:'DELETE', path:'/ocs/v2.php/apps/tables/api/2/tables/{id}' },
'table:scheme': { method:'GET', path:'/ocs/v2.php/apps/tables/api/2/tables/scheme/{id}' },
'table:transfer': { method:'PUT', path:'/ocs/v2.php/apps/tables/api/2/tables/{id}/transfer', body:['newOwnerUserId'] },
// Init
'init:index': { method:'GET', path:'/ocs/v2.php/apps/tables/api/2/init' },
// Columns (api v2)
'column:list': { method:'GET', path:'/ocs/v2.php/apps/tables/api/2/columns/{nodeType}/{nodeId}' },
'column:get': { method:'GET', path:'/ocs/v2.php/apps/tables/api/2/columns/{id}' },
'column:text': { method:'POST', path:'/ocs/v2.php/apps/tables/api/2/columns/text', body:['baseNodeId','title','textDefault','textMaxLength','textUnique','mandatory','baseNodeType','selectedViewIds'] },
'column:number': { method:'POST', path:'/ocs/v2.php/apps/tables/api/2/columns/number', body:['baseNodeId','title','numberDefault','numberDecimals','numberMin','numberMax','mandatory','baseNodeType'] },
'column:selection': { method:'POST', path:'/ocs/v2.php/apps/tables/api/2/columns/selection', body:['baseNodeId','title','selectionOptions','selectionDefault','mandatory','baseNodeType'] },
'column:datetime': { method:'POST', path:'/ocs/v2.php/apps/tables/api/2/columns/datetime', body:['baseNodeId','title','datetimeDefault','mandatory','baseNodeType'] },
'column:usergroup': { method:'POST', path:'/ocs/v2.php/apps/tables/api/2/columns/usergroup', body:['baseNodeId','title','usergroupDefault','usergroupMultipleItems','usergroupSelectUsers','usergroupSelectGroups','mandatory','baseNodeType'] },
// Rows (api v2)
'row:list': { method:'GET', path:'/ocs/v2.php/apps/tables/api/2/{nodeCollection}/{nodeId}/rows', query:['limit','offset'] },
'row:create': { method:'POST', path:'/ocs/v2.php/apps/tables/api/2/{nodeCollection}/{nodeId}/rows', body:['data'] },
// Generic row ops (api v1)
'row:get': { method:'GET', path:'/index.php/apps/tables/api/1/rows/{rowId}' },
'row:update': { method:'PUT', path:'/index.php/apps/tables/api/1/rows/{rowId}', body:['data'] },
'row:delete': { method:'DELETE', path:'/index.php/apps/tables/api/1/rows/{rowId}' },
// Views
'view:list': { method:'GET', path:'/index.php/apps/tables/api/1/tables/{tableId}/views' },
'view:get': { method:'GET', path:'/index.php/apps/tables/api/1/views/{viewId}' },
'view:create': { method:'POST', path:'/index.php/apps/tables/api/1/tables/{tableId}/views', body:['title','emoji'] },
'view:update': { method:'PUT', path:'/index.php/apps/tables/api/1/views/{viewId}', body:['data'] },
'view:delete': { method:'DELETE', path:'/index.php/apps/tables/api/1/views/{viewId}' },
// Shares
'share:listTable': { method:'GET', path:'/index.php/apps/tables/api/1/tables/{tableId}/shares' },
'share:listView': { method:'GET', path:'/index.php/apps/tables/api/1/views/{viewId}/shares' },
'share:create': { method:'POST', path:'/index.php/apps/tables/api/1/shares', body:['nodeId','nodeType','receiver','receiverType','permissionRead','permissionCreate','permissionUpdate','permissionDelete','permissionManage'] },
'share:update': { method:'PUT', path:'/index.php/apps/tables/api/1/shares/{shareId}', body:['permissionType','permissionValue'] },
'share:delete': { method:'DELETE', path:'/index.php/apps/tables/api/1/shares/{shareId}' },
'share:linkCreate': { method:'POST', path:'/ocs/v2.php/apps/tables/api/2/{nodeCollection}/{nodeId}/share', body:['password'] },
// Contexts
'context:list': { method:'GET', path:'/ocs/v2.php/apps/tables/api/2/contexts' },
'context:get': { method:'GET', path:'/ocs/v2.php/apps/tables/api/2/contexts/{contextId}' },
'context:create': { method:'POST', path:'/ocs/v2.php/apps/tables/api/2/contexts', body:['name','iconName','description'] },
'context:update': { method:'PUT', path:'/ocs/v2.php/apps/tables/api/2/contexts/{contextId}', body:['name','iconName','description'] },
'context:delete': { method:'DELETE', path:'/ocs/v2.php/apps/tables/api/2/contexts/{contextId}' },
// Favorites
'favorite:add': { method:'POST', path:'/ocs/v2.php/apps/tables/api/2/favorites/{nodeType}/{nodeId}' },
'favorite:remove': { method:'DELETE', path:'/ocs/v2.php/apps/tables/api/2/favorites/{nodeType}/{nodeId}' },
// Import
'import:table': { method:'POST', path:'/index.php/apps/tables/api/1/import/table/{tableId}', body:['path','createMissingColumns'] },
// Public rows
'public:rows': { method:'GET', path:'/ocs/v2.php/apps/tables/api/2/public/{token}/rows', query:['limit','offset'] },
'public:columns': { method:'GET', path:'/ocs/v2.php/apps/tables/api/2/public/{token}/columns' }
};
function TablesNode(config) {
RED.nodes.createNode(this, config);
var node = this;
this.configNode = RED.nodes.getNode(config.nextcloud);
this.operation = config.operation || 'table:list';
this.tableId = config.tableId; this.viewId = config.viewId; this.rowId = config.rowId;
this.shareId = config.shareId; this.nodeId = config.nodeId; this.nodeType = config.nodeType;
this.nodeCollection = config.nodeCollection; this.token = config.token; this.contextId = config.contextId;
this.bodyTitle = config.bodyTitle; this.bodyEmoji = config.bodyEmoji; this.bodyData = config.bodyData;
this.bodyName = config.bodyName; this.bodyReceiver = config.bodyReceiver; this.bodyReceiverType = config.bodyReceiverType;
this.bodyBaseNodeId = config.bodyBaseNodeId; this.bodyBaseNodeType = config.bodyBaseNodeType;
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(/\{id\}/g, msg.id || node.nodeId || '')
.replace(/\{tableId\}/g, msg.tableId || node.tableId || '')
.replace(/\{viewId\}/g, msg.viewId || node.viewId || '')
.replace(/\{rowId\}/g, msg.rowId || node.rowId || '')
.replace(/\{shareId\}/g, msg.shareId || node.shareId || '')
.replace(/\{nodeId\}/g, msg.nodeId || node.nodeId || '')
.replace(/\{nodeType\}/g, msg.nodeType || node.nodeType || 'table')
.replace(/\{nodeCollection\}/g, msg.nodeCollection || node.nodeCollection || 'tables')
.replace(/\{token\}/g, msg.token || node.token || '')
.replace(/\{contextId\}/g, msg.contextId || node.contextId || '');
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 = {
'Accept': 'application/json',
'Authorization': 'Basic ' + Buffer.from(username + ':' + password).toString('base64')
};
if (path.indexOf('/ocs/') === 0) headers['OCS-APIRequest'] = 'true';
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;
});
}
if (msg.data !== undefined) bodyObj.data = msg.data;
if (msg.body && typeof msg.body === 'object') Object.assign(bodyObj, msg.body);
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(chunk) { body += chunk; });
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 = { 'title': node.bodyTitle, 'emoji': node.bodyEmoji, 'name': node.bodyName,
'receiver': node.bodyReceiver, 'receiverType': node.bodyReceiverType,
'baseNodeId': node.bodyBaseNodeId, 'baseNodeType': node.bodyBaseNodeType,
'data': node.bodyData, 'limit': node.bodyLimit, 'offset': node.bodyOffset,
'password': node.bodyPassword, 'description': node.bodyDescription,
'template': node.bodyTemplate, 'nodeId': node.nodeId, 'nodeType': node.nodeType,
'newOwnerUserId': node.bodyNewOwnerId };
return m[name];
}
RED.nodes.registerType("tables", TablesNode);
};