@sync-in/server
Version:
The secure, open-source platform for file storage, sharing, collaboration, and sync
158 lines (157 loc) • 7.93 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
});
Object.defineProperty(exports, "LinksManager", {
enumerable: true,
get: function() {
return LinksManager;
}
});
const _common = require("@nestjs/common");
const _authmanagerservice = require("../../../authentication/services/auth-manager.service");
const _filesmanagerservice = require("../../files/services/files-manager.service");
const _spaces = require("../../spaces/constants/spaces");
const _spacesmanagerservice = require("../../spaces/services/spaces-manager.service");
const _usermodel = require("../../users/models/user.model");
const _usersmanagerservice = require("../../users/services/users-manager.service");
const _links = require("../constants/links");
const _linksqueriesservice = require("./links-queries.service");
function _ts_decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
function _ts_metadata(k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
}
let LinksManager = class LinksManager {
async linkValidation(identity, uuid) {
const [_link, check, ok] = await this.linkEnv(identity, uuid);
if (!ok) {
this.logger.warn(`${this.linkValidation.name} - ${uuid} : ${check}`);
}
const spaceLink = ok ? await this.linksQueries.spaceLink(uuid) : null;
if (spaceLink?.owner?.login) {
spaceLink.owner.avatar = await this.usersManager.getAvatarBase64(spaceLink.owner.login);
// for security reasons
delete spaceLink.owner.login;
}
return {
ok: ok,
error: ok ? null : check,
link: spaceLink
};
}
async linkAccess(identity, uuid, req, res) {
const [link, check, ok] = await this.linkEnv(identity, uuid);
if (!ok) {
this.logger.warn(`${this.linkAccess.name} - *${link.user.login}* (${link.user.id}) : ${check}`);
throw new _common.HttpException(check, _common.HttpStatus.BAD_REQUEST);
}
const user = new _usermodel.UserModel(link.user);
const spaceLink = await this.linksQueries.spaceLink(uuid);
if (!spaceLink.space && !spaceLink.share.isDir) {
// download the file (authentication has been verified before)
this.logger.log(`${this.linkAccess.name} - *${user.login}* (${user.id}) downloading ${spaceLink.share.name}`);
this.incrementLinkAccess(link);
const spaceEnv = await this.spaceEnvFromLink(user, spaceLink);
const sendFile = this.filesManager.sendFileFromSpace(spaceEnv, true, spaceLink.share.name);
try {
await sendFile.checks();
return await sendFile.stream(req, res);
} catch (e) {
this.logger.error(`${this.linkAccess.name} - unable to send file : ${e}`);
throw new _common.HttpException('Unable to download file', _common.HttpStatus.INTERNAL_SERVER_ERROR);
}
} else if (link.user.id !== identity.id) {
// authenticate user to allow access to the directory
this.logger.log(`${this.linkAccess.name} - *${user.login}* (${user.id}) is logged`);
this.incrementLinkAccess(link);
this.usersManager.updateAccesses(user, req.ip, true).catch((e)=>this.logger.error(`${this.linkAccess.name} - ${e}`));
return this.authManager.setCookies(user, res);
}
// already authenticated
}
async linkAuthentication(identity, uuid, linkPasswordDto, req, res) {
const [link, check, ok] = await this.linkEnv(identity, uuid, true);
if (!ok) {
this.logger.warn(`${this.linkAuthentication.name} - *${link.user.login}* (${link.user.id}) : ${check}`);
throw new _common.HttpException(check, _common.HttpStatus.BAD_REQUEST);
}
const authSuccess = await this.usersManager.compareUserPassword(link.user.id, linkPasswordDto.password);
const user = new _usermodel.UserModel(link.user);
this.usersManager.updateAccesses(user, req.ip, authSuccess).catch((e)=>this.logger.error(`${this.linkAuthentication.name} - ${e}`));
if (!authSuccess) {
this.logger.warn(`${this.linkAuthentication.name} - *${user.login}* (${user.id}) : auth failed`);
throw new _common.HttpException(_links.LINK_ERROR.UNAUTHORIZED, _common.HttpStatus.FORBIDDEN);
}
// authenticate user to allow access
this.logger.log(`${this.linkAuthentication.name} - *${user.login}* (${user.id}) is logged`);
return this.authManager.setCookies(user, res);
}
spaceEnvFromLink(user, link) {
return this.spacesManager.spaceEnv(user, [
link.space ? _spaces.SPACE_REPOSITORY.FILES : _spaces.SPACE_REPOSITORY.SHARES,
link.space ? link.space.alias : link.share.alias
]);
}
async linkEnv(identity, uuid, ignoreAuth = false) {
const link = await this.linksQueries.linkFromUUID(uuid);
const check = this.checkLink(identity, link, ignoreAuth);
const ok = check === true;
return [
link,
check,
ok
];
}
checkLink(identity, link, ignoreAuth = false) {
if (!link) {
return _links.LINK_ERROR.NOT_FOUND;
}
if (!link.user.isActive) {
return _links.LINK_ERROR.DISABLED;
}
if (link.limitAccess !== 0 && link.nbAccess >= link.limitAccess) {
return _links.LINK_ERROR.EXCEEDED;
}
if (link.expiresAt && new Date() >= link.expiresAt) {
return _links.LINK_ERROR.EXPIRED;
}
if (!ignoreAuth && link.requireAuth && link.user.id !== identity.id) {
return _links.LINK_ERROR.UNAUTHORIZED;
}
return true;
}
incrementLinkAccess(link) {
if (link.limitAccess !== null) {
this.linksQueries.incrementLinkAccess(link.uuid).catch((e)=>this.logger.error(`${this.incrementLinkAccess.name} - ${e}`));
}
}
constructor(authManager, usersManager, filesManager, spacesManager, linksQueries){
this.authManager = authManager;
this.usersManager = usersManager;
this.filesManager = filesManager;
this.spacesManager = spacesManager;
this.linksQueries = linksQueries;
this.logger = new _common.Logger(LinksManager.name);
}
};
LinksManager = _ts_decorate([
(0, _common.Injectable)(),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [
typeof _authmanagerservice.AuthManager === "undefined" ? Object : _authmanagerservice.AuthManager,
typeof _usersmanagerservice.UsersManager === "undefined" ? Object : _usersmanagerservice.UsersManager,
typeof _filesmanagerservice.FilesManager === "undefined" ? Object : _filesmanagerservice.FilesManager,
typeof _spacesmanagerservice.SpacesManager === "undefined" ? Object : _spacesmanagerservice.SpacesManager,
typeof _linksqueriesservice.LinksQueries === "undefined" ? Object : _linksqueriesservice.LinksQueries
])
], LinksManager);
//# sourceMappingURL=links-manager.service.js.map