2025-10-01 19:55:38 +02:00

366 lines
17 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var IResource_1 = require("../../../resource/v1/IResource");
var WebDAVRequest_1 = require("../WebDAVRequest");
var xml_js_builder_1 = require("xml-js-builder");
var Workflow_1 = require("../../../helper/Workflow");
var FSPath_1 = require("../../../manager/v1/FSPath");
var Errors_1 = require("../../../Errors");
var http = require("http");
function lockDiscovery(lockDiscoveryCache, arg, path, resource, callback) {
var cached = lockDiscoveryCache[path.toString()];
if (cached) {
callback(null, cached);
return;
}
var _Callback = callback;
callback = function (e, l) {
if (!e)
lockDiscoveryCache[path.toString()] = l;
_Callback(e, l);
};
arg.requireErPrivilege('canListLocks', resource, function (e, can) {
if (e || !can) {
callback(e, {});
return;
}
resource.getLocks(function (e, locks) {
var _a;
if (e === Errors_1.Errors.MustIgnore) {
locks = [];
}
else if (e) {
callback(e, null);
return;
}
if (resource.parent) {
var parentPath = path.getParent();
lockDiscovery(lockDiscoveryCache, arg, parentPath, resource.parent, function (e, l) {
if (e)
callback(e, null);
else {
l[path.toString()] = locks;
callback(null, l);
}
});
}
else
callback(null, (_a = {},
_a[path.toString()] = locks,
_a));
});
});
}
function parseRequestBody(arg) {
var allTrue = {
leftElements: [],
mustDisplay: function () { return true; },
mustDisplayValue: function () { return true; }
};
var onlyName = {
leftElements: [],
mustDisplay: function () { return true; },
mustDisplayValue: function () { return false; }
};
if (arg.contentLength <= 0)
return allTrue;
try {
var xml = xml_js_builder_1.XML.parse(arg.data);
var propfind = xml.find('DAV:propfind');
if (propfind.findIndex('DAV:propname') !== -1)
return onlyName;
if (propfind.findIndex('DAV:allprop') !== -1)
return allTrue;
var prop_1 = propfind.find('DAV:prop');
var fn = function (name) {
var index = prop_1.findIndex(name);
if (index === -1)
return false;
prop_1.elements.splice(index, 1);
return true;
};
return {
leftElements: prop_1.elements,
mustDisplay: fn,
mustDisplayValue: function () { return true; }
};
}
catch (ex) {
return allTrue;
}
}
function encode(url) {
return url;
}
function propstatStatus(status) {
return 'HTTP/1.1 ' + status + ' ' + http.STATUS_CODES[status];
}
function method(arg, callback) {
arg.getResource(function (e, resource) {
if (e || !resource) {
arg.setCode(WebDAVRequest_1.HTTPCodes.NotFound);
callback();
return;
}
var lockDiscoveryCache = {};
arg.checkIfHeader(resource, function () {
var targetSource = arg.isSource;
var multistatus = new xml_js_builder_1.XMLElementBuilder('D:multistatus', {
'xmlns:D': 'DAV:'
});
resource.type(function (e, type) { return process.nextTick(function () {
if (!type.isDirectory || arg.depth === 0) {
addXMLInfo(resource, multistatus, function (e) {
if (!e)
done(multistatus);
else {
if (e === Errors_1.Errors.BadAuthentication)
arg.setCode(WebDAVRequest_1.HTTPCodes.Unauthorized);
else
arg.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
callback();
}
});
return;
}
arg.requirePrivilege('canGetChildren', resource, function () {
resource.getChildren(function (e, children) { return process.nextTick(function () {
function err(e) {
if (e === Errors_1.Errors.BadAuthentication)
arg.setCode(WebDAVRequest_1.HTTPCodes.Unauthorized);
else
arg.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
callback();
}
addXMLInfo(resource, multistatus, function (e) {
if (e) {
err(e);
return;
}
new Workflow_1.Workflow()
.each(children, function (r, cb) { return addXMLInfo(r, multistatus, cb); })
.error(err)
.done(function () {
done(multistatus);
});
});
}); });
});
}); });
function addXMLInfo(resource, multistatus, _callback) {
var reqBody = parseRequestBody(arg);
var response = new xml_js_builder_1.XMLElementBuilder('D:response');
var callback = function (e) {
if (e === Errors_1.Errors.MustIgnore)
e = null;
else if (!e)
multistatus.add(response);
_callback(e);
};
var propstat = response.ele('D:propstat');
var privileges = [
'canGetCreationDate', 'canGetAvailableLocks', 'canGetLastModifiedDate', 'canGetMimeType', 'canGetProperties', 'canGetSize', 'canGetType', 'canGetWebName'
];
if (targetSource)
privileges.push('canSource');
arg.requireErPrivilege(privileges, resource, function (e, can) {
if (e) {
callback(e);
return;
}
if (!can) {
callback(Errors_1.Errors.BadAuthentication);
return;
}
propstat.ele('D:status').add('HTTP/1.1 200 OK');
var prop = propstat.ele('D:prop');
var nb = 1;
function nbOut(error) {
if (nb > 0 && error) {
nb = -1000;
callback(error);
return;
}
--nb;
if (nb === 0) {
if (reqBody.leftElements.length > 0) {
var propstatError = response.ele('D:propstat');
var prop_2 = propstatError.ele('D:prop');
propstatError.ele('D:status').add(propstatStatus(WebDAVRequest_1.HTTPCodes.NotFound));
for (var _i = 0, _a = reqBody.leftElements; _i < _a.length; _i++) {
var el = _a[_i];
if (el)
prop_2.ele(el.name);
}
}
callback();
}
}
var tags = {};
function mustDisplayTag(name) {
if (reqBody.mustDisplay('DAV:' + name))
tags[name] = {
el: prop.ele('D:' + name),
value: reqBody.mustDisplayValue('DAV:' + name)
};
else
tags[name] = {
value: false
};
}
mustDisplayTag('getlastmodified');
mustDisplayTag('lockdiscovery');
mustDisplayTag('supportedlock');
mustDisplayTag('creationdate');
mustDisplayTag('resourcetype');
mustDisplayTag('displayname');
mustDisplayTag('getetag');
function displayValue(values, fn) {
if (values.constructor === String ? tags[values].value : values.some(function (n) { return tags[n].value; })) {
++nb;
process.nextTick(fn);
}
}
displayValue('creationdate', function () {
resource.creationDate(function (e, ticks) { return process.nextTick(function () {
if (!e)
tags.creationdate.el.add(arg.dateISO8601(ticks));
nbOut(e);
}); });
});
++nb;
arg.getResourcePath(resource, function (e, path) {
if (e) {
nbOut(e);
return;
}
if (tags.lockdiscovery.value) {
++nb;
lockDiscovery(lockDiscoveryCache, arg, new FSPath_1.FSPath(path), resource, function (e, l) {
if (e) {
nbOut(e);
return;
}
for (var path_1 in l) {
for (var _i = 0, _a = l[path_1]; _i < _a.length; _i++) {
var _lock = _a[_i];
var lock = _lock;
var activelock = tags.lockdiscovery.el.ele('D:activelock');
activelock.ele('D:lockscope').ele('D:' + lock.lockKind.scope.value.toLowerCase());
activelock.ele('D:locktype').ele('D:' + lock.lockKind.type.value.toLowerCase());
activelock.ele('D:depth').add('Infinity');
if (lock.owner)
activelock.ele('D:owner').add(lock.owner);
activelock.ele('D:timeout').add('Second-' + (lock.expirationDate - Date.now()));
activelock.ele('D:locktoken').ele('D:href', undefined, true).add(lock.uuid);
activelock.ele('D:lockroot').ele('D:href', undefined, true).add(encode(arg.fullUri(path_1)));
}
}
nbOut(null);
});
}
resource.type(function (e, type) { return process.nextTick(function () {
if (e) {
nbOut(e);
return;
}
var p = encode(arg.fullUri(path));
var href = p.lastIndexOf('/') !== p.length - 1 && type.isDirectory ? p + '/' : p;
response.ele('D:href', undefined, true).add(href);
response.ele('D:location').ele('D:href', undefined, true).add(p);
if (tags.resourcetype.value && type.isDirectory)
tags.resourcetype.el.ele('D:collection');
if (type.isFile) {
mustDisplayTag('getcontentlength');
mustDisplayTag('getcontenttype');
if (tags.getcontenttype.value) {
++nb;
resource.mimeType(targetSource, function (e, mimeType) { return process.nextTick(function () {
if (!e)
tags.getcontenttype.el.add(mimeType);
nbOut(e);
}); });
}
if (tags.getcontentlength.value) {
++nb;
resource.size(targetSource, function (e, size) { return process.nextTick(function () {
if (!e)
tags.getcontentlength.el.add(size === undefined || size === null || size.constructor !== Number ? 0 : size);
nbOut(e);
}); });
}
}
nbOut();
}); });
});
displayValue('displayname', function () {
var methodDisplayName = resource.webName;
if (resource.displayName)
methodDisplayName = resource.displayName;
methodDisplayName.bind(resource)(function (e, name) { return process.nextTick(function () {
if (!e)
tags.displayname.el.add(name ? encode(name) : '');
nbOut(e);
}); });
});
displayValue('supportedlock', function () {
resource.getAvailableLocks(function (e, lockKinds) { return process.nextTick(function () {
if (e) {
nbOut(e);
return;
}
lockKinds.forEach(function (lockKind) {
var lockentry = tags.supportedlock.el.ele('D:lockentry');
var lockscope = lockentry.ele('D:lockscope');
lockscope.ele('D:' + lockKind.scope.value.toLowerCase());
var locktype = lockentry.ele('D:locktype');
locktype.ele('D:' + lockKind.type.value.toLowerCase());
});
nbOut();
}); });
});
displayValue(['getetag', 'getlastmodified'], function () {
resource.lastModifiedDate(function (e, lastModifiedDate) { return process.nextTick(function () {
if (!e) {
if (tags.getetag.value)
tags.getetag.el.add(IResource_1.ETag.createETag(lastModifiedDate));
if (tags.getlastmodified.value)
tags.getlastmodified.el.add(new Date(lastModifiedDate).toUTCString());
}
nbOut(e);
}); });
});
++nb;
process.nextTick(function () {
resource.getProperties(function (e, properties) { return process.nextTick(function () {
if (e) {
nbOut(e);
return;
}
for (var name_1 in properties) {
if (reqBody.mustDisplay(name_1)) {
var tag = prop.ele(name_1);
if (reqBody.mustDisplayValue(name_1))
tag.add(properties[name_1]);
}
}
nbOut();
}); });
});
nbOut();
});
}
function done(multistatus) {
arg.setCode(WebDAVRequest_1.HTTPCodes.MultiStatus);
arg.writeXML(multistatus);
callback();
}
});
});
}
exports.method = method;
method.isValidFor = function (type) {
return !!type;
};
exports.default = method;