@nephele/adapter-virtual
Version:
Virtual resource adapter for the Nephele WebDAV server.
131 lines • 4.4 kB
JavaScript
import { BadGatewayError, MethodNotImplementedError, MethodNotSupportedError, ResourceNotFoundError, } from 'nephele';
import Resource from './Resource.js';
export default class Adapter {
constructor({ files }) {
this.files = files;
}
urlToRelativePath(url, baseUrl) {
if (!decodeURIComponent(url.pathname)
.replace(/\/?$/, () => '/')
.startsWith(decodeURIComponent(baseUrl.pathname))) {
return null;
}
return ('/' +
decodeURIComponent(url.pathname)
.substring(decodeURIComponent(baseUrl.pathname).length)
.replace(/^\/?/, '')
.replace(/\/?$/, ''));
}
basename(path) {
return (path
.split('/')
.filter((part) => part != '')
.pop() || path);
}
dirname(path) {
const parts = path.split('/').filter((part) => part != '');
parts.pop();
return ['', ...parts].join('/');
}
async getComplianceClasses(_url, _request, _response) {
return ['2'];
}
async getAllowedMethods(_url, _request, _response) {
return [];
}
async getOptionsResponseCacheControl(_url, _request, _response) {
return 'max-age=604800';
}
async isAuthorized(url, method, baseUrl, user) {
let access = 'u';
if (['GET', 'HEAD', 'COPY', 'OPTIONS', 'PROPFIND'].includes(method)) {
access = 'r';
}
if (['POST', 'PUT', 'DELETE', 'MOVE', 'MKCOL', 'PROPPATCH'].includes(method)) {
access = 'w';
}
if (['SEARCH'].includes(method)) {
access = 'x';
}
if (['LOCK', 'UNLOCK'].includes(method)) {
access = 'w';
}
if (access === 'u') {
return false;
}
if (access === 'w') {
try {
const resource = await this.getResource(url, baseUrl);
if ('owner' in resource.file.properties &&
resource.file.properties.owner !== user.username) {
return false;
}
}
catch (e) {
try {
const urlPath = this.urlToRelativePath(url, baseUrl);
if (urlPath == null) {
return false;
}
const parent = await this.getResource(new URL(this.dirname(url.pathname), baseUrl), baseUrl);
if ('owner' in parent.file.properties &&
parent.file.properties.owner !== user.username) {
return false;
}
}
catch (e) {
if (e instanceof ResourceNotFoundError) {
return true;
}
throw e;
}
}
}
return true;
}
async getResource(url, baseUrl) {
const path = this.urlToRelativePath(url, baseUrl);
if (path == null) {
throw new BadGatewayError('The given path is not managed by this server.');
}
const resource = new Resource({
adapter: this,
baseUrl,
path,
});
if (!resource.exists) {
throw new ResourceNotFoundError('Resource not found.');
}
return resource;
}
async newResource(url, baseUrl) {
const path = this.urlToRelativePath(url, baseUrl);
if (path == null) {
throw new BadGatewayError('The given path is not managed by this server.');
}
return new Resource({
adapter: this,
baseUrl,
path,
});
}
async newCollection(url, baseUrl) {
const path = this.urlToRelativePath(url, baseUrl);
if (path == null) {
throw new BadGatewayError('The given path is not managed by this server.');
}
return new Resource({
adapter: this,
baseUrl,
path,
collection: true,
});
}
getMethod(method) {
if (method === 'POST' || method === 'PATCH') {
throw new MethodNotSupportedError('Method not supported.');
}
throw new MethodNotImplementedError('Method not implemented.');
}
}
//# sourceMappingURL=Adapter.js.map