@sync-in/server
Version:
The secure, open-source platform for file storage, sharing, collaboration, and sync
241 lines (240 loc) • 10.4 kB
JavaScript
/*
* Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>
* This file is part of Sync-in | The open source file sync and share solution
* See the LICENSE file for licensing details
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: Object.getOwnPropertyDescriptor(all, name).get
});
}
_export(exports, {
get IsRealPathIsDirAndExists () {
return IsRealPathIsDirAndExists;
},
get dbFileFromSpace () {
return dbFileFromSpace;
},
get quotaKeyFromSpace () {
return quotaKeyFromSpace;
},
get realPathFromRootFile () {
return realPathFromRootFile;
},
get realPathFromSpace () {
return realPathFromSpace;
},
get realTrashPathFromSpace () {
return realTrashPathFromSpace;
}
});
const _common = require("@nestjs/common");
const _promises = /*#__PURE__*/ _interop_require_default(require("node:fs/promises"));
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
const _fileerror = require("../../files/models/file-error");
const _usermodel = require("../../users/models/user.model");
const _cache = require("../constants/cache");
const _spaces = require("../constants/spaces");
const _spacemodel = require("../models/space.model");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
async function IsRealPathIsDirAndExists(rPath) {
try {
const stats = await _promises.default.stat(rPath);
if (!stats.isDirectory()) {
throw new _fileerror.FileError(_common.HttpStatus.BAD_REQUEST, 'Location is not a directory');
}
} catch (e) {
if (e instanceof _fileerror.FileError) {
throw new _fileerror.FileError(e.httpCode, e.message);
}
if (e.code === 'ENOENT') {
throw new _fileerror.FileError(_common.HttpStatus.NOT_FOUND, 'Location not found');
}
throw new _fileerror.FileError(_common.HttpStatus.BAD_REQUEST, e.message);
}
}
function realPathFromSpace(user, space, withBasePath = false) {
let bPath;
let fPath;
if (space.inPersonalSpace) {
// personal user space (ignore root alias)
bPath = _usermodel.UserModel.getRepositoryPath(user.login, space.inTrashRepository);
fPath = space.paths;
} else if (space.root?.externalPath) {
// external path from space or share
bPath = space.root.externalPath;
if (space.inSharesRepository && space.root.file?.path) {
// child share with an external path and file.id
fPath = [
...space.root.file.path.split('/'),
...space.paths
];
} else {
fPath = space.paths;
}
} else if (space.root.file?.path && space.root.owner?.login) {
// space root linked to a file in a personal space
bPath = _nodepath.default.join(_usermodel.UserModel.getRepositoryPath(space.root.owner.login, space.root.file.inTrash), space.root.file.path);
fPath = space.paths;
} else if (space.root.file?.space?.id) {
// share case
if (space.root.file.root?.id) {
// share linked to a file in a root space with an external path or directly to the root space
bPath = _nodepath.default.join(space.root.file.root.externalPath, space.root.file.path || '');
} else {
// share linked to a file in a space
bPath = _nodepath.default.join(_spacemodel.SpaceModel.getRepositoryPath(space.root.file.space.alias, space.root.file.inTrash), space.root.file.path || '');
}
fPath = space.paths;
} else if (space.alias) {
// space files (no root)
bPath = _spacemodel.SpaceModel.getRepositoryPath(space.alias, space.inTrashRepository);
fPath = [
space.root.alias,
...space.paths
];
} else {
throw new _fileerror.FileError(_common.HttpStatus.NOT_FOUND, 'Space root not found');
}
const rPath = _nodepath.default.resolve(bPath, ...fPath);
// prevent path traversal
if (!rPath.startsWith(bPath)) {
throw new _fileerror.FileError(_common.HttpStatus.FORBIDDEN, 'Location is not allowed');
}
return withBasePath ? [
bPath,
rPath
] : rPath;
}
function realTrashPathFromSpace(user, space) {
if (space.inPersonalSpace) {
// personal user space
return _usermodel.UserModel.getTrashPath(user.login);
} else if (space.root?.externalPath) {
// external path from space or share
if (space.root.file?.space?.alias) {
// space case
return _spacemodel.SpaceModel.getTrashPath(space.root.file.space.alias);
}
// share case
// todo: store the deleted files in the same path with .trash ?
return null;
} else if (space.root?.file?.path && space.root.owner?.login) {
// space root is linked to a file in a personal space
return _usermodel.UserModel.getTrashPath(space.root.owner.login);
} else if (space.root?.file?.space?.id) {
// share linked to a space (with an external path or not)
return _spacemodel.SpaceModel.getTrashPath(space.root.file.space.alias);
} else if (space.alias) {
// space files (no root)
return _spacemodel.SpaceModel.getTrashPath(space.alias);
} else {
return null;
}
}
function realPathFromRootFile(f) {
// get realpath
if (f.origin) {
// share case (the order of the tests is important)
if (f.origin.ownerLogin) {
return _nodepath.default.join(_usermodel.UserModel.getRepositoryPath(f.origin.ownerLogin, f.inTrash), f.path);
} else if (f.root.externalPath) {
// in case of share child from a share with external path, child share should have an external path and a fileId (file path)
return _nodepath.default.join(f.root.externalPath, f.path || '');
} else if (f.origin.spaceRootExternalPath) {
return _nodepath.default.join(f.origin.spaceRootExternalPath, f.path);
} else if (f.origin.spaceAlias) {
return _nodepath.default.join(_spacemodel.SpaceModel.getRepositoryPath(f.origin.spaceAlias, f.inTrash), f.path);
}
} else {
// space case
if (f.root.owner.login) {
return _nodepath.default.join(_usermodel.UserModel.getRepositoryPath(f.root.owner.login, f.inTrash), f.path);
} else if (f.root.externalPath) {
return f.root.externalPath;
}
}
return undefined;
}
function dbFileFromSpace(userId, space) {
const dbFile = {};
dbFile.inTrash = space.repository === _spaces.SPACE_REPOSITORY.TRASH;
if (space.inPersonalSpace) {
// personal user space (ignore root alias)
dbFile.ownerId = userId;
dbFile.path = _nodepath.default.join(...space.paths);
dbFile.inTrash = space.inTrashRepository;
} else if (space.root?.externalPath) {
// external path from space or share
dbFile.spaceId = space.inSharesRepository ? null : space.id;
dbFile.spaceExternalRootId = space.inSharesRepository ? null : space.root.id;
if (space.inSharesRepository) {
// in this case space.id is the share.id
// if the `externalParentShareId` property is defined, it's an external child share that must use the parent id
dbFile.shareExternalId = space.root?.externalParentShareId ? space.root.externalParentShareId : space.id;
} else {
dbFile.shareExternalId = null;
}
if (space.inSharesRepository && space.root.file?.path) {
// child share with an external path and file.id
dbFile.path = _nodepath.default.join(space.root.file.path, ...space.paths);
} else {
dbFile.path = _nodepath.default.join(...space.paths);
}
} else if (space.root.file?.path && space.root.owner?.login) {
// space root linked to a file in a personal space
dbFile.ownerId = space.root.owner.id;
dbFile.inTrash = space.root.file.inTrash;
dbFile.path = _nodepath.default.join(space.root.file.path, ...space.paths);
} else if (space.root.file?.space?.id) {
// share linked to a file in a space file or an external space root
dbFile.spaceId = space.root.file.space.id;
dbFile.spaceExternalRootId = space.root.file.root?.id || null;
dbFile.shareExternalId = null;
if (space.root.file.id) {
dbFile.inTrash = space.root.file.inTrash;
}
dbFile.path = _nodepath.default.join(space.root.file.path || '', ...space.paths);
} else if (space.id) {
// space files (no root)
dbFile.spaceId = space.id;
dbFile.spaceExternalRootId = null;
dbFile.path = _nodepath.default.join(space.root.alias, ...space.paths);
dbFile.inTrash = space.inTrashRepository;
} else {
throw new _fileerror.FileError(_common.HttpStatus.NOT_FOUND, 'Space root not found');
}
return dbFile;
}
function quotaKeyFromSpace(userId, space) {
if (space.inPersonalSpace) {
// personal user space
return `${_cache.CACHE_QUOTA_USER_PREFIX}-${userId}`;
} else if (space.root?.externalPath) {
// external paths are managed by admin, set a quota on a root is not intended
return null;
} else if (space.root.file?.path && space.root.owner?.login) {
// space root is linked on a user file
return `${_cache.CACHE_QUOTA_USER_PREFIX}-${space.root.owner.id}`;
} else if (space.root.file?.space?.id) {
if (space.root.file.root?.id) {
// share linked to a root space with an external path, set a quota on a root is not intended
return null;
} else {
return `${_cache.CACHE_QUOTA_SPACE_PREFIX}-${space.root.file.space.id}`;
}
} else if (space.id) {
return `${_cache.CACHE_QUOTA_SPACE_PREFIX}-${space.id}`;
} else {
throw new _fileerror.FileError(_common.HttpStatus.NOT_FOUND, 'Space root not found');
}
}
//# sourceMappingURL=paths.js.map